def test_simple_matvec(self): class VerificationComp(SimpleCompDerivMatVec): def jacobian(self, params, unknowns, resids): raise RuntimeError("Derivative functions on this comp should not run.") def apply_linear(self, params, unknowns, dparams, dunknowns, dresids, mode): raise RuntimeError("Derivative functions on this comp should not run.") sub = Group() sub.add('mycomp', VerificationComp()) prob = Problem() prob.root = Group() prob.root.add('sub', sub) prob.root.add('x_param', IndepVarComp('x', 1.0)) prob.root.connect('x_param.x', "sub.mycomp.x") sub.fd_options['force_fd'] = True prob.setup(check=False) prob.run() J = prob.calc_gradient(['x_param.x'], ['sub.mycomp.y'], mode='fwd', return_format='dict') assert_rel_error(self, J['sub.mycomp.y']['x_param.x'][0][0], 2.0, 1e-6) J = prob.calc_gradient(['x_param.x'], ['sub.mycomp.y'], mode='rev', return_format='dict') assert_rel_error(self, J['sub.mycomp.y']['x_param.x'][0][0], 2.0, 1e-6)
def setup(self): self.add_subsystem('px', IndepVarComp('x', 1.0), promotes=['x']) self.add_subsystem('pz', IndepVarComp('z', np.array([5.0, 2.0])), promotes=['z']) sub = self.add_subsystem('sub', Group(), promotes=[ 'x', 'z', 'y1', 'state_eq.y2_actual', 'state_eq.y2_command', 'd1.y2', 'd2.y2' ]) subgrp = sub.add_subsystem( 'state_eq_group', Group(), promotes=['state_eq.y2_actual', 'state_eq.y2_command']) subgrp.add_subsystem('state_eq', StateConnection()) sub.add_subsystem('d1', SellarDis1withDerivatives(), promotes=['x', 'z', 'y1']) sub.add_subsystem('d2', SellarDis2withDerivatives(), promotes=['z', 'y1']) self.connect('state_eq.y2_command', 'd1.y2') self.connect('d2.y2', 'state_eq.y2_actual') self.add_subsystem('obj_cmp', ExecComp('obj = x**2 + z[1] + y1 + exp(-y2)', z=np.array([0.0, 0.0]), x=0.0, y1=0.0, y2=0.0), promotes=['x', 'z', 'y1', 'obj']) self.connect('d2.y2', 'obj_cmp.y2') 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']) self.connect('d2.y2', 'con_cmp2.y2') nl = self.options['nonlinear_solver'] self.nonlinear_solver = nl() if inspect.isclass(nl) else nl if self.options['nl_atol']: self.nonlinear_solver.options['atol'] = self.options['nl_atol'] if self.options['nl_maxiter']: self.nonlinear_solver.options['maxiter'] = self.options[ 'nl_maxiter'] ln = self.options['linear_solver'] self.linear_solver = ln() if inspect.isclass(ln) else ln if self.options['ln_atol']: self.linear_solver.options['atol'] = self.options['ln_atol'] if self.options['ln_maxiter']: self.linear_solver.options['maxiter'] = self.options['ln_maxiter']
def test_incompatible_connections(self): class BadComp(Component): def __init__(self): super(BadComp, self).__init__() self.add_param('x2', 100.0, units='m') self.add_output('x3', 100.0) # Explicit Connection prob = Problem() prob.root = Group() prob.root.add('src', SrcComp()) prob.root.add('dest', BadComp()) prob.root.connect('src.x2', 'dest.x2') with self.assertRaises(TypeError) as cm: prob.setup(check=False) expected_msg = "Unit 'degC' in source 'src.x2' is incompatible with unit 'm' in target 'dest.x2'." self.assertEqual(str(cm.exception), expected_msg) # Implicit Connection prob = Problem() prob.root = Group() prob.root.add('src', SrcComp(), promotes=['x2']) prob.root.add('dest', BadComp(),promotes=['x2']) with self.assertRaises(TypeError) as cm: prob.setup(check=False) expected_msg = "Unit 'degC' in source 'x2' is incompatible with unit 'm' in target 'x2'." self.assertEqual(str(cm.exception), expected_msg)
def test_double_arraycomp(self): # Mainly testing a bug in the array return for multiple arrays group = Group() group.add('x_param1', ParamComp('x1', np.ones((2))), promotes=['*']) group.add('x_param2', ParamComp('x2', np.ones((2))), promotes=['*']) group.add('mycomp', DoubleArrayComp(), promotes=['*']) prob = Problem() prob.root = group prob.root.ln_solver = ScipyGMRES() prob.setup(check=False) prob.run() Jbase = group.mycomp.JJ J = prob.calc_gradient(['x1', 'x2'], ['y1', 'y2'], mode='fwd', return_format='array') diff = np.linalg.norm(J - Jbase) assert_rel_error(self, diff, 0.0, 1e-8) J = prob.calc_gradient(['x1', 'x2'], ['y1', 'y2'], mode='fd', return_format='array') diff = np.linalg.norm(J - Jbase) assert_rel_error(self, diff, 0.0, 1e-8)
def test_conflicting_connections(self): # verify we get an error if we have conflicting implicit and explicit connections root = Group() # promoting G1.x will create an implicit connection to G3.x # this is a conflict because G3.x (aka G3.C4.x) is already connected # to G3.C3.x G2 = root.add('G2', Group(), promotes=['x']) # BAD PROMOTE G2.add('C1', ParamComp('x', 5.), promotes=['x']) G1 = G2.add('G1', Group(), promotes=['x']) G1.add('C2', ExecComp('y=x*2.0'), promotes=['x']) G3 = root.add('G3', Group(), promotes=['x']) G3.add('C3', ExecComp('y=x*2.0')) G3.add('C4', ExecComp('y=x*2.0'), promotes=['x']) root.connect('G2.G1.C2.y', 'G3.C3.x') G3.connect('C3.y', 'x') prob = Problem(root) try: prob.setup(check=False) except Exception as error: msg = "Target 'G3.C4.x' is connected to multiple unknowns: ['G2.C1.x', 'G3.C3.y']" self.assertEqual(text_type(error), msg) else: self.fail("Error expected")
def test_conflicting_promotions(self): # verify we get an error if we have conflicting promotions root = Group() # promoting G1.x will create an implicit connection to G3.x # this is a conflict because G3.x (aka G3.C4.x) is already connected # to G3.C3.x G2 = root.add('G2', Group()) G2.add('C1', ParamComp('x', 5.), promotes=['x']) G1 = G2.add('G1', Group(), promotes=['x']) G1.add('C2', ExecComp('y=x*2.0'), promotes=['x']) G3 = root.add('G3', Group(), promotes=['x']) G3.add('C3', ExecComp('y=x*2.0'), promotes=['y']) # promoting y G3.add('C4', ExecComp('y=x*2.0'), promotes=['x', 'y']) # promoting y again.. BAD prob = Problem(root) try: prob.setup(check=False) except Exception as error: msg = "Promoted name 'G3.y' matches multiple unknowns: ['G3.C3.y', 'G3.C4.y']" self.assertEqual(text_type(error), msg) else: self.fail("Error expected")
def __init__(self): super(ConvergeDivergeGroups, self).__init__() self.add('p', IndepVarComp('x', 2.0)) sub1 = self.add('sub1', Group()) sub1.add('comp1', Comp1()) sub2 = sub1.add('sub2', Group()) sub2.add('comp2', Comp2()) sub2.add('comp3', Comp3()) sub1.add('comp4', Comp4()) sub3 = self.add('sub3', Group()) sub3.add('comp5', Comp5()) sub3.add('comp6', Comp6()) self.add('comp7', Comp7()) self.connect("p.x", "sub1.comp1.x1") self.connect('sub1.comp1.y1', 'sub1.sub2.comp2.x1') self.connect('sub1.comp1.y2', 'sub1.sub2.comp3.x1') self.connect('sub1.sub2.comp2.y1', 'sub1.comp4.x1') self.connect('sub1.sub2.comp3.y1', 'sub1.comp4.x2') self.connect('sub1.comp4.y1', 'sub3.comp5.x1') self.connect('sub1.comp4.y2', 'sub3.comp6.x1') self.connect('sub3.comp5.y1', 'comp7.x1') self.connect('sub3.comp6.y1', 'comp7.x2')
def test_add(self): group = Group() comp = ExecComp('y=x*2.0') group.add('mycomp', comp) subs = list(group.subsystems()) self.assertEqual(len(subs), 1) self.assertEqual(subs[0], comp) self.assertEqual(subs[0].name, 'mycomp') comp2 = ExecComp('y=x*2.0') group.add("nextcomp", comp2) subs = list(group.subsystems()) self.assertEqual(len(subs), 2) self.assertEqual(subs[0], comp) self.assertEqual(subs[1], comp2) with self.assertRaises(RuntimeError) as cm: group.add('mycomp', comp) expected_msg = "Group '' already contains a subsystem with name 'mycomp'." self.assertEqual(str(cm.exception), expected_msg)
def test_heat_exchanger(self): comp = HeatExchanger() g = Group() g.add('comp', comp) p = Problem(root=g) p.setup() comp.params['flow_in:in:Tt'] = 1423.8 comp.params['flow_in:in:Pt'] = 0.302712118187 comp.params['flow_in:in:W'] = 1.0 comp.params['dPqP'] = 0.0 comp.params['design'] = True p.run() TOL = 0.005 assert_rel_error(self, comp.unknowns['flow_out:out:Tt'], 539.94, TOL) assert_rel_error(self, comp.unknowns['Qreleased'], 327.22, TOL) assert_rel_error(self, comp.unknowns['Qabsorbed'], 327.22, TOL) assert_rel_error(self, comp.unknowns['Qmax'], 335.1, TOL) assert_rel_error(self, comp.unknowns['T_cold_out'], 749.96, TOL) #check off design comp.params['design'] = False p.run() assert_rel_error(self, comp.unknowns['flow_out:out:Tt'], 539.94, TOL) assert_rel_error(self, comp.unknowns['Qreleased'], 327.22, TOL) assert_rel_error(self, comp.unknowns['Qabsorbed'], 327.22, TOL) assert_rel_error(self, comp.unknowns['Qmax'], 335.1, TOL) assert_rel_error(self, comp.unknowns['T_cold_out'], 749.96, TOL)
def __init__(self): super(SellarStateConnection, self).__init__() self.add('px', IndepVarComp('x', 1.0), promotes=['*']) self.add('pz', IndepVarComp('z', np.array([5.0, 2.0])), promotes=['*']) sub = self.add('sub', Group(), promotes=['*']) sub.ln_solver = ScipyGMRES() subgrp = sub.add('state_eq_group', Group(), promotes=['*']) subgrp.ln_solver = ScipyGMRES() subgrp.add('state_eq', StateConnection()) sub.add('d1', SellarDis1withDerivatives(), promotes=['x', 'z', 'y1']) sub.add('d2', SellarDis2withDerivatives(), promotes=['z', 'y1']) self.connect('state_eq.y2_command', 'd1.y2') self.connect('d2.y2', 'state_eq.y2_actual') self.add('obj_cmp', ExecComp('obj = x**2 + z[1] + y1 + exp(-y2)', z=np.array([0.0, 0.0]), x=0.0, y1=0.0, y2=0.0), promotes=['x', 'z', 'y1', 'obj']) self.connect('d2.y2', 'obj_cmp.y2') self.add('con_cmp1', ExecComp('con1 = 3.16 - y1'), promotes=['con1', 'y1']) self.add('con_cmp2', ExecComp('con2 = y2 - 24.0'), promotes=['con2']) self.connect('d2.y2', 'con_cmp2.y2') self.nl_solver = Newton()
def test_inp_inp_promoted_no_src(self): p = Problem(root=Group()) root = p.root G1 = root.add("G1", Group()) G2 = G1.add("G2", Group()) C1 = G2.add("C1", ExecComp('y=x*2.0')) C2 = G2.add("C2", ExecComp('y=x*2.0')) G3 = root.add("G3", Group()) G4 = G3.add("G4", Group()) C3 = G4.add("C3", ExecComp('y=x*2.0'), promotes=['x']) C4 = G4.add("C4", ExecComp('y=x*2.0'), promotes=['x']) stream = cStringIO() checks = p.setup(out_stream=stream) self.assertEqual(checks['dangling_params'], ['G1.G2.C1.x', 'G1.G2.C2.x', 'G3.G4.x']) self.assertEqual(checks['no_connect_comps'], ['G1.G2.C1', 'G1.G2.C2', 'G3.G4.C3', 'G3.G4.C4']) self.assertEqual(p._dangling['G3.G4.x'], set(['G3.G4.C3.x', 'G3.G4.C4.x'])) # setting promoted name should set both params mapped to that name since the # params are dangling. p['G3.G4.x'] = 999. self.assertEqual(p.root.G3.G4.C3.params['x'], 999.) self.assertEqual(p.root.G3.G4.C4.params['x'], 999.)
def test_unconnected_param_access_with_promotes(self): prob = Problem(root=Group()) G1 = prob.root.add('G1', Group()) G2 = G1.add('G2', Group(), promotes=['x']) C1 = G2.add('C1', ExecComp(['y=2.0*x', 'z=x*x-2.0']), promotes=['x']) C2 = G2.add('C2', ExecComp(['y=2.0*x', 'z=x*x-2.0'])) G2.connect('C1.y', 'C2.x') # ignore warning about the unconnected param with warnings.catch_warnings(record=True) as w: warnings.simplefilter("ignore") prob.setup(check=False) prob.run() # still must use absolute naming to find params even if they're # promoted. Promoted names for params can refer to more than one param. C1.params['x'] = 2. self.assertEqual(prob['G1.x'], 2.0) self.assertEqual(prob.root.G1.G2.C1.params['x'], 2.0) prob['G1.x'] = 99. self.assertEqual(C1.params['x'], 99.) prob['G1.x'] = 12. self.assertEqual(C1.params['x'], 12.) prob['G1.x'] = 17. self.assertEqual(prob.root.G1.G2.C1.params['x'], 17.0) prob.run()
def test_explicit_connection_errors(self): class A(Component): def __init__(self): super(A, self).__init__() self.add_state('x', 0) class B(Component): def __init__(self): super(B, self).__init__() self.add_param('x', 0) prob = Problem() prob.root = Group() prob.root.add('A', A()) prob.root.add('B', B()) prob.root.connect('A.x', 'B.x') prob.setup(check=False) expected_error_message = ( "Source 'A.y' cannot be connected to target 'B.x': " "'A.y' does not exist.") prob = Problem() prob.root = Group() prob.root.add('A', A()) prob.root.add('B', B()) prob.root.connect('A.y', 'B.x') with self.assertRaises(ConnectError) as cm: prob.setup(check=False) self.assertEqual(str(cm.exception), expected_error_message) expected_error_message = ( "Source 'A.x' cannot be connected to target 'B.y': " "'B.y' does not exist.") prob = Problem() prob.root = Group() prob.root.add('A', A()) prob.root.add('B', B()) prob.root.connect('A.x', 'B.y') with self.assertRaises(ConnectError) as cm: prob.setup(check=False) self.assertEqual(str(cm.exception), expected_error_message) expected_error_message = ( "Source 'A.x' cannot be connected to target 'A.x': " "Target must be a parameter but 'A.x' is an unknown.") prob = Problem() prob.root = Group() prob.root.add('A', A()) prob.root.add('B', B()) prob.root.connect('A.x', 'A.x') with self.assertRaises(ConnectError) as cm: prob.setup(check=False) self.assertEqual(str(cm.exception), expected_error_message)
def test_splitterW(self): g = Group() p = Problem(root=g) comp = g.add('comp', SplitterW()) p.setup(check=False) comp.params['W1_des'] = 1.08 comp.params['MNexit1_des'] = 1.0 comp.params['MNexit2_des'] = 1.0 comp.params['design'] = True comp.params['flow_in:in:W'] = 3.48771299 comp.params['flow_in:in:Tt'] = 630.74523 comp.params['flow_in:in:Pt'] = 0.0271945 comp.params['flow_in:in:Mach'] = 1.0 p.run() self.check(comp) comp.params['design'] = False comp.params['flow_out_1:in:is_super'] = True comp.params['flow_out_2:in:is_super'] = True p.run() self.check(comp) comp.params['flow_in:in:W'] *= 0.95 comp.params['flow_out_1:in:is_super'] = False comp.params['flow_out_2:in:is_super'] = False p.run() TOL = 0.001 assert_rel_error(self, comp.unknowns['flow_out_1:out:Mach'], 0.76922, TOL) assert_rel_error(self, comp.unknowns['flow_out_2:out:Mach'], 0.76922, TOL)
def setUp(self): model = Group() ivc = IndepVarComp() mapdata = SampleMap() params = mapdata.param_data x, y, z = params outs = mapdata.output_data z = outs[0] ivc.add_output('x', x['default'], units=x['units']) ivc.add_output('y', y['default'], units=y['units']) ivc.add_output('z', z['default'], units=z['units']) model.add_subsystem('des_vars', ivc, promotes=["*"]) comp = MetaModelStructured(method='slinear', extrapolate=True) for param in params: comp.add_input(param['name'], param['default'], param['values']) for out in outs: comp.add_output(out['name'], out['default'], out['values']) model.add_subsystem('comp', comp, promotes=["*"]) self.prob = Problem(model) self.prob.setup() self.prob['x'] = 1.0 self.prob['y'] = 0.75 self.prob['z'] = -1.7
class CycleComponentTestCase(unittest.TestCase): def setUp(self): '''Initialization function called before every test function''' self.g = Group() self.comp1 = DummyComp() self.comp2 = DummyComp() self.g.add('comp1', self.comp1) self.g.add('comp2', self.comp2) self.p = Problem(root=self.g) self.p.setup() def tearDown(self): '''Function called after every test function''' self.g = None self.p = None def test_copy_flow(self): self.comp1.params['flow:in:W'] = 100.0 self.comp1.params['flow:in:Tt'] = 518.0 self.comp1.params['flow:in:Pt'] = 15.0 CycleComponent.copy_from(self.comp1, 'flow', self.comp2, 'flow') self.p.run() TOL = 0.0001 assert_rel_error(self, self.comp2.unknowns['flow:out:Tt'], 518.0, TOL) assert_rel_error(self, self.comp2.unknowns['flow:out:Pt'], 15.0, TOL)
def test_inp_inp_promoted_w_explicit_src(self): p = Problem(root=Group()) root = p.root G1 = root.add("G1", Group()) G2 = G1.add("G2", Group(), promotes=['x']) C1 = G2.add("C1", ExecComp('y=x*2.0')) C2 = G2.add("C2", ParamComp('x', 1.0), promotes=['x']) G3 = root.add("G3", Group()) G4 = G3.add("G4", Group(), promotes=['x']) C3 = G4.add("C3", ExecComp('y=x*2.0'), promotes=['x']) C4 = G4.add("C4", ExecComp('y=x*2.0'), promotes=['x']) p.root.connect('G1.x', 'G3.x') p.setup(check=False) self.assertEqual(p._dangling['G1.G2.C1.x'], set(['G1.G2.C1.x'])) self.assertEqual(len(p._dangling), 1) # setting promoted name will set the value into the unknowns, but will # not propagate it to the params. That will happen during run(). p['G1.x'] = 999. self.assertEqual(p.root.G3.G4.C3.params['x'], 0.) self.assertEqual(p.root.G3.G4.C4.params['x'], 0.) p.run() self.assertEqual(p.root.G3.G4.C3.params['x'], 999.) self.assertEqual(p.root.G3.G4.C4.params['x'], 999.)
def test_simple_matvec(self): class VerificationComp(SimpleCompDerivMatVec): def jacobian(self, params, unknowns, resids): raise RuntimeError("Derivative functions on this comp should not run.") def apply_linear(self, params, unknowns, dparams, dunknowns, dresids, mode): raise RuntimeError("Derivative functions on this comp should not run.") sub = Group() sub.add("mycomp", VerificationComp()) prob = Problem() prob.root = Group() prob.root.add("sub", sub) prob.root.add("x_param", ParamComp("x", 1.0)) prob.root.connect("x_param.x", "sub.mycomp.x") sub.fd_options["force_fd"] = True prob.setup(check=False) prob.run() J = prob.calc_gradient(["x_param.x"], ["sub.mycomp.y"], mode="fwd", return_format="dict") assert_rel_error(self, J["sub.mycomp.y"]["x_param.x"][0][0], 2.0, 1e-6) J = prob.calc_gradient(["x_param.x"], ["sub.mycomp.y"], mode="rev", return_format="dict") assert_rel_error(self, J["sub.mycomp.y"]["x_param.x"][0][0], 2.0, 1e-6)
def test_polar_high_lift(): """ Tests ComputePolar """ # Need to plug Cd modules, Reynolds and Oswald input_list = [ "data:aerodynamics:aircraft:takeoff:mach", "data:geometry:wing:area", "data:geometry:wing:span", "data:geometry:fuselage:maximum_height", "data:geometry:fuselage:maximum_width", "data:geometry:wing:root:chord", "data:geometry:wing:tip:chord", "data:geometry:wing:sweep_25", "data:geometry:wing:thickness_ratio", "data:geometry:wing:wetted_area", "data:geometry:wing:MAC:length", "data:geometry:fuselage:length", "data:geometry:fuselage:wetted_area", "data:geometry:horizontal_tail:MAC:length", "data:geometry:horizontal_tail:thickness_ratio", "data:geometry:horizontal_tail:sweep_25", "data:geometry:horizontal_tail:wetted_area", "data:geometry:vertical_tail:MAC:length", "data:geometry:vertical_tail:thickness_ratio", "data:geometry:vertical_tail:sweep_25", "data:geometry:vertical_tail:wetted_area", "data:geometry:propulsion:pylon:length", "data:geometry:propulsion:nacelle:length", "data:geometry:propulsion:pylon:wetted_area", "data:geometry:propulsion:nacelle:wetted_area", "data:geometry:propulsion:engine:count", "data:geometry:propulsion:fan:length", "data:geometry:aircraft:wetted_area", "tuning:aerodynamics:aircraft:cruise:CD:k", "tuning:aerodynamics:aircraft:cruise:CD:offset", "tuning:aerodynamics:aircraft:cruise:CD:winglet_effect:k", "tuning:aerodynamics:aircraft:cruise:CD:winglet_effect:offset", "data:aerodynamics:high_lift_devices:takeoff:CL", "data:aerodynamics:high_lift_devices:takeoff:CD", ] group = Group() group.add_subsystem("reynolds", ComputeReynolds(low_speed_aero=True), promotes=["*"]) group.add_subsystem("oswald", OswaldCoefficient(low_speed_aero=True), promotes=["*"]) group.add_subsystem("cd0", CD0(low_speed_aero=True), promotes=["*"]) group.add_subsystem("cd_trim", CdTrim(low_speed_aero=True), promotes=["*"]) group.add_subsystem("polar", ComputePolar(type=PolarType.TAKEOFF), promotes=["*"]) ivc = get_indep_var_comp(input_list) ivc.add_output("data:aerodynamics:aircraft:low_speed:CL", np.arange(0.0, 1.5, 0.01)) problem = run_system(group, ivc) cd = problem["data:aerodynamics:aircraft:takeoff:CD"] cl = problem["data:aerodynamics:aircraft:takeoff:CL"] assert cd[cl == 1.0] == approx(0.091497, abs=1e-5) assert cd[cl == 1.5] == approx(0.180787, abs=1e-5)
def test_calc_gradient(self): root = Group() parm = root.add("parm", ParamComp("x", np.array([1.0, 1.0, 1.0, 1.0]))) comp = root.add("comp", RosenSuzuki()) root.connect("parm.x", "comp.x") prob = Problem(root) prob.setup(check=False) prob.run() param_list = ["parm.x"] unknown_list = ["comp.f", "comp.g"] # check that calc_gradient returns proper dict value when mode is 'fwd' J = prob.calc_gradient(param_list, unknown_list, mode="fwd", return_format="dict") np.testing.assert_almost_equal(J["comp.f"]["parm.x"], np.array([[-3.0, -3.0, -17.0, 9.0]])) np.testing.assert_almost_equal( J["comp.g"]["parm.x"], np.array([[3.0, 1.0, 3.0, 1.0], [1.0, 4.0, 2.0, 3.0], [6.0, 1.0, 2.0, -1.0]]) ) # check that calc_gradient returns proper array value when mode is 'fwd' J = prob.calc_gradient(param_list, unknown_list, mode="fwd", return_format="array") np.testing.assert_almost_equal( J, np.array([[-3.0, -3.0, -17.0, 9.0], [3.0, 1.0, 3.0, 1.0], [1.0, 4.0, 2.0, 3.0], [6.0, 1.0, 2.0, -1.0]]) ) # check that calc_gradient returns proper dict value when mode is 'rev' J = prob.calc_gradient(param_list, unknown_list, mode="rev", return_format="dict") np.testing.assert_almost_equal(J["comp.f"]["parm.x"], np.array([[-3.0, -3.0, -17.0, 9.0]])) np.testing.assert_almost_equal( J["comp.g"]["parm.x"], np.array([[3.0, 1.0, 3.0, 1.0], [1.0, 4.0, 2.0, 3.0], [6.0, 1.0, 2.0, -1.0]]) ) # check that calc_gradient returns proper array value when mode is 'rev' J = prob.calc_gradient(param_list, unknown_list, mode="rev", return_format="array") np.testing.assert_almost_equal( J, np.array([[-3.0, -3.0, -17.0, 9.0], [3.0, 1.0, 3.0, 1.0], [1.0, 4.0, 2.0, 3.0], [6.0, 1.0, 2.0, -1.0]]) ) # check that calc_gradient returns proper dict value when mode is 'fd' J = prob.calc_gradient(param_list, unknown_list, mode="fd", return_format="dict") np.testing.assert_almost_equal(J["comp.f"]["parm.x"], np.array([[-3.0, -3.0, -17.0, 9.0]]), decimal=5) np.testing.assert_almost_equal( J["comp.g"]["parm.x"], np.array([[3.0, 1.0, 3.0, 1.0], [1.0, 4.0, 2.0, 3.0], [6.0, 1.0, 2.0, -1.0]]), decimal=5, ) # check that calc_gradient returns proper array value when mode is 'fd' J = prob.calc_gradient(param_list, unknown_list, mode="fd", return_format="array") np.testing.assert_almost_equal( J, np.array([[-3.0, -3.0, -17.0, 9.0], [3.0, 1.0, 3.0, 1.0], [1.0, 4.0, 2.0, 3.0], [6.0, 1.0, 2.0, -1.0]]), decimal=5, )
def test_nested_conn(self): # tests a self contained connection under a Group nested at least 3 levels # down from the Problem prob = Problem(root=Group()) root = prob.root G1 = root.add('G1', Group()) G2 = G1.add('G2', Group()) C1 = G2.add('C1', ParamComp('x', 5.)) C2 = G2.add('C2', ExecComp('y=x*2.0')) G2.connect('C1.x', 'C2.x') prob.setup(check=False)
def setUp(self): self.p = Problem(root=Group()) root = self.p.root self.G1 = root.add("G1", Group()) self.G2 = self.G1.add("G2", Group()) self.C1 = self.G2.add("C1", ExecComp('y=x*2.0')) self.C2 = self.G2.add("C2", ParamComp('x', 1.0)) self.G3 = root.add("G3", Group()) self.G4 = self.G3.add("G4", Group()) self.C3 = self.G4.add("C3", ExecComp('y=x*2.0')) self.C4 = self.G4.add("C4", ExecComp('y=x*2.0'))
def test_array2D_index_connection(self): group = Group() group.add('x_param', IndepVarComp('x', np.ones((2, 2))), promotes=['*']) sub = group.add('sub', Group(), promotes=['*']) sub.add('mycomp', ArrayComp2D(), promotes=['x', 'y']) group.add('obj', ExecComp('b = a')) group.connect('y', 'obj.a', src_indices=[3]) prob = Problem() prob.root = group prob.root.ln_solver = LinearGaussSeidel() prob.setup(check=False) prob.run() J = prob.calc_gradient(['x'], ['obj.b'], mode='fwd', return_format='dict') Jbase = prob.root.sub.mycomp._jacobian_cache assert_rel_error(self, Jbase[('y', 'x')][3][0], J['obj.b']['x'][0][0], 1e-8) assert_rel_error(self, Jbase[('y', 'x')][3][1], J['obj.b']['x'][0][1], 1e-8) assert_rel_error(self, Jbase[('y', 'x')][3][2], J['obj.b']['x'][0][2], 1e-8) assert_rel_error(self, Jbase[('y', 'x')][3][3], J['obj.b']['x'][0][3], 1e-8) J = prob.calc_gradient(['x'], ['obj.b'], mode='rev', return_format='dict') Jbase = prob.root.sub.mycomp._jacobian_cache assert_rel_error(self, Jbase[('y', 'x')][3][0], J['obj.b']['x'][0][0], 1e-8) assert_rel_error(self, Jbase[('y', 'x')][3][1], J['obj.b']['x'][0][1], 1e-8) assert_rel_error(self, Jbase[('y', 'x')][3][2], J['obj.b']['x'][0][2], 1e-8) assert_rel_error(self, Jbase[('y', 'x')][3][3], J['obj.b']['x'][0][3], 1e-8)
def test_multiple_connect(self): root = Group() C1 = root.add('C1', ExecComp('y=x*2.0')) C2 = root.add('C2', ExecComp('y=x*2.0')) C3 = root.add('C3', ExecComp('y=x*2.0')) root.connect('C1.y', ['C2.x', 'C3.x']) root._setup_paths('') params_dict, unknowns_dict = root._setup_variables() # verify we get correct connection information connections = root._get_explicit_connections() expected_connections = {'C2.x': ['C1.y'], 'C3.x': ['C1.y']} self.assertEqual(connections, expected_connections)
def setUp(self): self.comp = comp = Nozzle() g = Group() g.add('comp', comp) self.p = p = Problem(root=g) p.setup(check=False) comp.params['flow_in:in:W'] = 100.0 comp.params['flow_in:in:Tt'] = 700.0 comp.params['flow_in:in:Pt'] = 50.0 comp.params['flow_in:in:Mach'] = 0.40 comp.params['back_Ps'] = 15.0 comp.params['design'] = True p.run()
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(root=Group(), impl=impl) top = p.root top.add("C1", InOutArrayComp(size)) top.add("C2", DistribOverlappingInputComp(size)) top.connect('C1.outvec', 'C2.invec') p.setup(check=False) top.C1.params['invec'] = np.array(range(size, 0, -1), float) p.run() self.assertTrue( all(top.C2.unknowns['outvec'][:4] == np.array(range(size, 0, -1), float)[:4] * 4)) self.assertTrue( all(top.C2.unknowns['outvec'][8:] == np.array(range(size, 0, -1), float)[8:] * 4)) # overlapping part should be double size of the rest self.assertTrue( all(top.C2.unknowns['outvec'][4:8] == np.array(range(size, 0, -1), float)[4:8] * 8))
def test_array_values(self): prob = Problem() prob.root = Group() prob.root.add('pc', ParamComp('x', np.zeros((2, 3)), units='degC'), promotes=['x']) prob.root.add('uc', UnitComp(shape=(2, 3), param_name='x', out_name='x_out', units='degF'), promotes=['x', 'x_out']) prob.setup(check=False) prob.run() assert_rel_error(self, prob['x_out'], np.array([[32., 32., 32.], [32., 32., 32.]]), 1e-6) param_list = ['x'] unknown_list = ['x_out'] # Forward Mode J = prob.calc_gradient(param_list, unknown_list, mode='fwd', return_format='dict') assert_rel_error(self, J['x_out']['x'], 1.8 * np.eye(6), 1e-6) # Reverse Mode J = prob.calc_gradient(param_list, unknown_list, mode='rev', return_format='dict') assert_rel_error(self, J['x_out']['x'], 1.8 * np.eye(6), 1e-6)
def test_bad_size(self): class BadComp(SimpleArrayComp): def jacobian(self, params, unknowns, resids): """Analytical derivatives""" J = {} J[('y', 'x')] = np.zeros((3, 3)) return J prob = Problem() prob.root = Group() prob.root.add('comp', BadComp()) prob.root.add('p1', ParamComp('x', np.ones([2]))) prob.root.connect('p1.x', 'comp.x') prob.setup(check=False) prob.run() try: data = prob.check_partial_derivatives(out_stream=None) except Exception as err: msg = "Jacobian in component 'comp' between the" + \ " variables 'x' and 'y' is the wrong size. " + \ "It should be 2 by 2" self.assertEqual(str(err), msg) else: self.fail("Error expected")
def setup(self): self.add_subsystem('px', IndepVarComp('x', 1.0), promotes=['x']) self.add_subsystem('pz', IndepVarComp('z', np.array([5.0, 2.0])), promotes=['z']) self.mda = mda = self.add_subsystem('mda', Group(), promotes=['x', 'z', 'y1', 'y2']) mda.add_subsystem('d1', SellarDis1withDerivatives(), promotes=['x', 'z', 'y1', 'y2']) mda.add_subsystem('d2', SellarDis2withDerivatives(), promotes=['z', 'y1', 'y2']) self.add_subsystem('obj_cmp', ExecComp('obj = x**2 + z[1] + y1 + exp(-y2)', z=np.array([0.0, 0.0]), x=0.0, y1=0.0, y2=0.0), promotes=['obj', 'x', 'z', 'y1', 'y2']) 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']) nl = self.options['nonlinear_solver'] self.nonlinear_solver = nl() if inspect.isclass(nl) else nl if self.options['nl_atol']: self.nonlinear_solver.options['atol'] = self.options['nl_atol'] if self.options['nl_maxiter']: self.nonlinear_solver.options['maxiter'] = self.options['nl_maxiter'] ln = self.options['linear_solver'] self.linear_solver = ln() if inspect.isclass(ln) else ln if self.options['ln_atol']: self.linear_solver.options['atol'] = self.options['ln_atol'] if self.options['ln_maxiter']: self.linear_solver.options['maxiter'] = self.options['ln_maxiter']
def test_simple_jac(self): group = Group() group.add('x_param', ParamComp('x', 1.0), promotes=['*']) group.add('mycomp', ExecComp(['y=2.0*x']), promotes=['x', 'y']) prob = Problem() prob.root = group prob.root.ln_solver = ScipyGMRES() prob.setup(check=False) prob.run() J = prob.calc_gradient(['x'], ['y'], mode='fwd', return_format='dict') assert_rel_error(self, J['y']['x'][0][0], 2.0, 1e-6) J = prob.calc_gradient(['x'], ['y'], mode='rev', return_format='dict') assert_rel_error(self, J['y']['x'][0][0], 2.0, 1e-6)
def __init__(self): super(SellarNoDerivatives, self).__init__() self.add('px', IndepVarComp('x', 1.0), promotes=['x']) self.add('pz', IndepVarComp('z', np.array([5.0, 2.0])), promotes=['z']) cycle = self.add('cycle', Group(), promotes=['x', 'z', 'y1', 'y2']) cycle.ln_solver = ScipyGMRES() cycle.add('d1', SellarDis1(), promotes=['x', 'z', 'y1', 'y2']) cycle.add('d2', SellarDis2(), promotes=['z', 'y1', 'y2']) self.add('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('con_cmp1', ExecComp('con1 = 3.16 - y1'), promotes=['con1', 'y1']) self.add('con_cmp2', ExecComp('con2 = y2 - 24.0'), promotes=['con2', 'y2']) self.nl_solver = NLGaussSeidel() self.cycle.d1.deriv_options['type'] = 'fd' self.cycle.d2.deriv_options['type'] = 'fd'
def test_driver_records_metadata(self): size = 3 prob = Problem(Group(), impl=impl) G1 = prob.root.add('G1', ParallelGroup()) G1.add('P1', IndepVarComp('x', np.ones(size, float) * 1.0)) G1.add('P2', IndepVarComp('x', np.ones(size, float) * 2.0)) prob.root.add('C1', ABCDArrayComp(size)) prob.root.connect('G1.P1.x', 'C1.a') prob.root.connect('G1.P2.x', 'C1.b') prob.driver.add_recorder(self.recorder) self.recorder.options['record_metadata'] = True prob.setup(check=False) prob.cleanup() expected = ( list(prob.root.params.iteritems()), list(prob.root.unknowns.iteritems()), list(prob.root.resids.iteritems()), ) self.assertMetadataRecorded(expected)
def __init__(self): super(ExampleGroup, self).__init__() self.G2 = self.add('G2', Group()) self.C1 = self.G2.add('C1', IndepVarComp('x', 5.)) self.G1 = self.G2.add('G1', Group()) self.C2 = self.G1.add('C2', ExecComp('y=x*2.0', x=3., y=5.5)) self.G3 = self.add('G3', Group()) self.C3 = self.G3.add('C3', ExecComp('y=x*2.0', x=3., y=5.5)) self.C4 = self.G3.add('C4', ExecComp('y=x*2.0', x=3., y=5.5)) self.G2.connect('C1.x', 'G1.C2.x') self.connect('G2.G1.C2.y', 'G3.C3.x') self.G3.connect('C3.y', 'C4.x')
def test_parallel_diamond(self): size = 3 prob = Problem(Group(), impl=impl) root = prob.root root.add('P1', ParamComp('x', np.ones(size, float) * 1.1)) G1 = root.add('G1', ParallelGroup()) G1.add('C1', ABCDArrayComp(size)) G1.add('C2', ABCDArrayComp(size)) root.add('C3', ABCDArrayComp(size)) root.connect('P1.x', 'G1.C1.a') root.connect('P1.x', 'G1.C2.b') root.connect('G1.C1.c', 'C3.a') root.connect('G1.C2.d', 'C3.b') prob.setup(check=False) prob.run() if not MPI or self.comm.rank == 0: assert_rel_error(self, prob.root.G1.C1.unknowns['c'], np.ones(size) * 2.1, 1.e-10) assert_rel_error(self, prob.root.G1.C1.unknowns['d'], np.ones(size) * .1, 1.e-10) assert_rel_error(self, prob.root.C3.params['a'], np.ones(size) * 2.1, 1.e-10) assert_rel_error(self, prob.root.C3.params['b'], np.ones(size) * -.1, 1.e-10) if not MPI or self.comm.rank == 1: assert_rel_error(self, prob.root.G1.C2.unknowns['c'], np.ones(size) * 2.1, 1.e-10) assert_rel_error(self, prob.root.G1.C2.unknowns['d'], np.ones(size) * -.1, 1.e-10)
def setup(self): self.add_subsystem('px', IndepVarComp('x', 1.0), promotes=['x']) self.add_subsystem('pz', IndepVarComp('z', np.array([5.0, 2.0])), promotes=['z']) cycle = self.add_subsystem('cycle', Group(), promotes=['x', 'z', 'y1', 'y2']) cycle.add_subsystem('d1', SellarDis1(), promotes=['x', 'z', 'y1', 'y2']) cycle.add_subsystem('d2', SellarDis2(), promotes=['z', 'y1', 'y2']) 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']) self.nonlinear_solver = NonlinearBlockGS() self.nonlinear_solver = self.options['nonlinear_solver'] if self.options['nl_atol']: self.nonlinear_solver.options['atol'] = self.options['nl_atol'] if self.options['nl_maxiter']: self.nonlinear_solver.options['maxiter'] = self.options[ 'nl_maxiter']
def test_simple_matvec(self): group = Group() group.add('x_param', IndepVarComp('x', 1.0), promotes=['*']) group.add('mycomp', SimpleCompDerivMatVec(), promotes=['x', 'y']) prob = Problem() prob.root = group prob.root.ln_solver = LinearGaussSeidel() prob.setup(check=False) prob.run() J = prob.calc_gradient(['x'], ['y'], mode='fwd', return_format='dict') assert_rel_error(self, J['y']['x'][0][0], 2.0, 1e-6) J = prob.calc_gradient(['x'], ['y'], mode='rev', return_format='dict') assert_rel_error(self, J['y']['x'][0][0], 2.0, 1e-6)
def build_sequence(child_factory, num_children, conns=(), parent=None): if parent is None: parent = Group() cnames = [] for i in range(num_children): child = child_factory() cname = _child_name(child, i) parent.add(cname, child) if i: for u,v in conns: parent.connect('.'.join((cnames[-1],u)), '.'.join((cname,v))) cnames.append(cname) return parent
def test_simple(self): prob = Problem(Group(), impl=impl) size = 5 A1 = prob.root.add('A1', ParamComp('a', np.zeros(size, float))) B1 = prob.root.add('B1', ParamComp('b', np.zeros(size, float))) B2 = prob.root.add('B2', ParamComp('b', np.zeros(size, float))) S1 = prob.root.add('S1', ParamComp('s', '')) L1 = prob.root.add('L1', ParamComp('l', [])) C1 = prob.root.add('C1', ABCDArrayComp(size)) C2 = prob.root.add('C2', ABCDArrayComp(size)) prob.root.connect('A1.a', 'C1.a') prob.root.connect('B1.b', 'C1.b') # prob.root.connect('S1:s', 'C1.in_string') # prob.root.connect('L1:l', 'C1.in_list') prob.root.connect('C1.c', 'C2.a') prob.root.connect('B2.b', 'C2.b') # prob.root.connect('C1.out_string', 'C2.in_string') # prob.root.connect('C1.out_list', 'C2.in_list') prob.setup(check=False) prob['A1.a'] = np.ones(size, float) * 3.0 prob['B1.b'] = np.ones(size, float) * 7.0 prob['B2.b'] = np.ones(size, float) * 5.0 prob.run() self.assertTrue(all(prob['C2.a'] == np.ones(size, float) * 10.)) self.assertTrue(all(prob['C2.b'] == np.ones(size, float) * 5.)) self.assertTrue(all(prob['C2.c'] == np.ones(size, float) * 15.)) self.assertTrue(all(prob['C2.d'] == np.ones(size, float) * 5.))
def test_simple_paraboloid_equality(self): prob = Problem() root = prob.root = Group() root.add('p1', ParamComp('x', 50.0), promotes=['*']) root.add('p2', ParamComp('y', 50.0), promotes=['*']) root.add('comp', Paraboloid(), promotes=['*']) root.add('con', ExecComp('c = 15.0 - x + y'), promotes=['*']) prob.driver = ScipyOptimizer() prob.driver.options['optimizer'] = 'SLSQP' prob.driver.options['tol'] = 1.0e-8 prob.driver.add_param('x', low=-50.0, high=50.0) prob.driver.add_param('y', low=-50.0, high=50.0) prob.driver.add_objective('f_xy') prob.driver.add_constraint('c', ctype='ineq') prob.driver.options['disp'] = False prob.setup(check=False) prob.run() # Minimum should be at (7.166667, -7.833334) assert_rel_error(self, prob['x'], 7.16667, 1e-6) assert_rel_error(self, prob['y'], -7.833334, 1e-6)
def test_simple_array_comp(self): prob = Problem() root = prob.root = Group() root.add('p1', ParamComp('x', np.zeros([2])), promotes=['*']) root.add('comp', SimpleArrayComp(), promotes=['*']) root.add('con', ExecComp('c = y - 20.0', c=np.array([0.0, 0.0]), y=np.array([0.0, 0.0])), promotes=['*']) root.add('obj', ExecComp('o = y[0]', y=np.array([0.0, 0.0])), promotes=['*']) prob.driver = pyOptSparseDriver() prob.driver.add_param('x', low=-50.0, high=50.0) prob.driver.add_objective('o') prob.driver.add_constraint('c', ctype='eq') prob.setup(check=False) prob.run() obj = prob['o'] assert_rel_error(self, obj, 20.0, 1e-6)
def test_simple_array_comp2D(self): prob = Problem() root = prob.root = Group() root.add('p1', ParamComp('x', np.zeros((2, 2))), promotes=['*']) root.add('comp', ArrayComp2D(), promotes=['*']) root.add('con', ExecComp('c = y - 20.0', c=np.zeros((2, 2)), y=np.zeros((2, 2))), promotes=['*']) root.add('obj', ExecComp('o = y[0, 0]', y=np.zeros((2, 2))), promotes=['*']) prob.driver = ScipyOptimizer() prob.driver.options['optimizer'] = 'SLSQP' prob.driver.add_param('x', low=-50.0, high=50.0) prob.driver.add_objective('o') prob.driver.add_constraint('c', ctype='eq') prob.driver.options['disp'] = False prob.setup(check=False) prob.run() obj = prob['o'] assert_rel_error(self, obj, 20.0, 1e-6)
def __init__(self): super(ExampleByObjGroup, self).__init__() self.G2 = self.add('G2', Group()) self.C1 = self.G2.add('C1', IndepVarComp('x', 'foo')) self.G1 = self.G2.add('G1', Group()) self.C2 = self.G1.add('C2', SimplePassByObjComp()) self.G3 = self.add('G3', Group()) self.C3 = self.G3.add('C3', SimplePassByObjComp()) self.C4 = self.G3.add('C4', SimplePassByObjComp()) self.G2.connect('C1.x', 'G1.C2.x') self.connect('G2.G1.C2.y', 'G3.C3.x') self.G3.connect('C3.y', 'C4.x')
def make_subtree(parent, nsubgroups, levels, ncomps, ninputs, noutputs, nconns, var_factory=float): """Construct a system subtree under the given parent group.""" if levels <= 0: return if levels == 1: # add leaf nodes create_dyncomps(parent, ncomps, ninputs, noutputs, nconns, var_factory=var_factory) else: # add more subgroup levels for i in range(nsubgroups): g = parent.add_subsystem("G%d" % i, Group()) make_subtree(g, nsubgroups, levels - 1, ncomps, ninputs, noutputs, nconns, var_factory=var_factory)
def __init__(self): super(SellarDerivativesGrouped, self).__init__() self.add('px', IndepVarComp('x', 1.0), promotes=['*']) self.add('pz', IndepVarComp('z', np.array([5.0, 2.0])), promotes=['*']) mda = self.add('mda', Group(), promotes=['*']) mda.ln_solver = ScipyGMRES() mda.add('d1', SellarDis1withDerivatives(), promotes=['*']) mda.add('d2', SellarDis2withDerivatives(), promotes=['*']) self.add('obj_cmp', ExecComp('obj = x**2 + z[1] + y1 + exp(-y2)', z=np.array([0.0, 0.0]), x=0.0, y1=0.0, y2=0.0), promotes=['*']) self.add('con_cmp1', ExecComp('con1 = 3.16 - y1'), promotes=['*']) self.add('con_cmp2', ExecComp('con2 = y2 - 24.0'), promotes=['*']) mda.nl_solver = NLGaussSeidel() mda.d1.fd_options['force_fd'] = True mda.d2.fd_options['force_fd'] = True self.ln_solver = ScipyGMRES()
def test_shape(self): import numpy as np from openmdao.api import Group, Problem, IndepVarComp from openmdao.components.meta_model_structured import MetaModelStructured # create input param training data, of sizes 25, 5, and 10 points resp. p1 = np.linspace(0, 100, 25) p2 = np.linspace(-10, 10, 5) p3 = np.linspace(0, 1, 10) # can use meshgrid to create a 3D array of test data P1, P2, P3 = np.meshgrid(p1, p2, p3, indexing='ij') f = np.sqrt(P1) + P2 * P3 # verify the shape matches the order and size of the input params print(f.shape) # Create regular grid interpolator instance interp = MetaModelStructured(method='cubic') interp.add_input('p1', 0.5, p1) interp.add_input('p2', 0.0, p2) interp.add_input('p3', 3.14, p3) interp.add_output('f', 0.0, f) # Set up the OpenMDAO model model = Group() model.add_subsystem('comp', interp, promotes=["*"]) prob = Problem(model) prob.setup() # set inputs prob['p1'] = 55.12 prob['p2'] = -2.14 prob['p3'] = 0.323 prob.run_model() computed = prob['f'] actual = 6.73306472 assert_almost_equal(computed, actual) # we can verify all gradients by checking against finit-difference prob.check_partials(compact_print=True)
def test_compressor(self): comp = Compressor() g = Group() g.add('comp', comp) p = Problem(root=g) p.setup() comp.params['PR_des'] = 12.47 comp.params['MNexit_des'] = 0.4 comp.params['eff_des'] = 0.8 comp.params['flow_in:in:W'] = 1.08 comp.params['flow_in:in:Tt'] = 630.74523 comp.params['flow_in:in:Pt'] = 0.0271945 comp.params['flow_in:in:Mach'] = 0.6 comp.params['design'] = True p.run() TOL = 0.001 assert_rel_error(self, comp.unknowns['flow_out:out:W'], 1.08, TOL) assert_rel_error(self, comp.unknowns['flow_out:out:Pt'], 0.33899, TOL) assert_rel_error(self, comp.unknowns['flow_out:out:Tt'], 1424.01, TOL) assert_rel_error(self, comp.unknowns['flow_out:out:rhos'], 0.000594, TOL) assert_rel_error(self, comp.unknowns['flow_out:out:Mach'], 0.4 ,TOL) assert_rel_error(self, comp.unknowns['flow_out:out:area'], 364.7, TOL) assert_rel_error(self, comp.unknowns['pwr'], 303.2, TOL) assert_rel_error(self, comp.unknowns['eff_poly'], 0.8545, TOL) # run off design comp.params['design'] = False p.run() # values should remain unchanged in off-design at design condition assert_rel_error(self, comp.unknowns['flow_out:out:W'], 1.08, TOL) assert_rel_error(self, comp.unknowns['flow_out:out:Pt'], 0.33899, TOL) assert_rel_error(self, comp.unknowns['flow_out:out:Tt'], 1424.01, TOL) assert_rel_error(self, comp.unknowns['flow_out:out:rhos'], 0.000594, TOL) assert_rel_error(self, comp.unknowns['flow_out:out:Mach'], 0.4 ,TOL) assert_rel_error(self, comp.unknowns['flow_out:out:area'], 364.7, TOL) assert_rel_error(self, comp.unknowns['pwr'], 303.2, TOL) assert_rel_error(self, comp.unknowns['eff_poly'], 0.8545, TOL) # try changing something comp.params['flow_in:in:W'] *= 1.1 p.run() assert_rel_error(self, comp.unknowns['PR'], 13.52995, TOL)
def test_nozzle_very_low_temperatures(self): comp = Nozzle() g = Group() g.add('comp', comp) p = Problem(root=g) p.setup(check=False) comp.params['flow_in:in:W'] = 0.639 comp.params['flow_in:in:Tt'] = 540.0 comp.params['flow_in:in:Pt'] = 0.34 comp.params['flow_in:in:Mach'] = 0.4 comp.params['back_Ps'] = 0.0272 comp.params['design'] = True p.run() TOL = 0.01 #this test needs larger tollerance due to exteremely low temperatures assert_rel_error(self, comp.unknowns['flow_out:out:W'], 0.639, TOL) assert_rel_error(self, comp.unknowns['flow_out:out:Pt'], 0.34, TOL) assert_rel_error(self, comp.unknowns['flow_out:out:Tt'], 540.0, TOL) assert_rel_error(self, comp.unknowns['flow_out:out:Mach'], 2.7092, TOL) assert_rel_error(self, comp.unknowns['flow_out:out:area'], 264.204, TOL) assert_rel_error(self, comp.unknowns['flow_out:out:rhos'], .000177443, TOL) assert_rel_error(self, comp.unknowns['Fg'], 38.98, TOL) #off design calcs comp.params['design'] = False p.run() self.assertEqual(comp.unknowns['switchRegime'], 'PERFECTLY_EXPANDED') assert_rel_error(self, comp.unknowns['flow_out:out:W'], 0.639, TOL) assert_rel_error(self, comp.unknowns['flow_out:out:Pt'], 0.34, TOL) assert_rel_error(self, comp.unknowns['flow_out:out:Tt'], 540.0, TOL) assert_rel_error(self, comp.unknowns['flow_out:out:Mach'], 2.7092, TOL) assert_rel_error(self, comp.unknowns['flow_out:out:area'], 264.204, TOL) assert_rel_error(self, comp.unknowns['flow_out:out:rhos'], 0.000177443, TOL) comp.params['back_Ps'] = 0.03 p.run() self.assertEqual(comp.unknowns['switchRegime'], 'OVEREXPANDED') comp.params['back_Ps'] = 0.026 p.run() self.assertEqual(comp.unknowns['switchRegime'], 'UNDEREXPANDED')
def test_simple_in_group_matvec(self): group = Group() sub = group.add('sub', Group(), promotes=['x', 'y']) group.add('x_param', ParamComp('x', 1.0), promotes=['*']) sub.add('mycomp', SimpleCompDerivMatVec(), promotes=['x', 'y']) prob = Problem() prob.root = group prob.root.ln_solver = ExplicitSolver() prob.setup(check=False) prob.run() J = prob.calc_gradient(['x'], ['y'], mode='fwd', return_format='dict') assert_rel_error(self, J['y']['x'][0][0], 2.0, 1e-6) J = prob.calc_gradient(['x'], ['y'], mode='rev', return_format='dict') assert_rel_error(self, J['y']['x'][0][0], 2.0, 1e-6)
def test_src_indices_error(self): size = 3 group = Group() group.add('P', IndepVarComp('x', numpy.ones(size))) group.add('C1', DistribExecComp(['y=2.0*x'], arr_size=size, x=numpy.zeros(size), y=numpy.zeros(size))) group.add('C2', ExecComp(['z=3.0*y'], y=numpy.zeros(size), z=numpy.zeros(size))) prob = Problem(impl=impl) prob.root = group prob.root.ln_solver = LinearGaussSeidel() prob.root.connect('P.x', 'C1.x') prob.root.connect('C1.y', 'C2.y') prob.driver.add_desvar('P.x') prob.driver.add_objective('C1.y') try: prob.setup(check=False) except Exception as err: self.assertEqual(str(err), "'C1.y' is a distributed variable and may not be used as a " "design var, objective, or constraint.") else: if MPI: # pragma: no cover self.fail("Exception expected")
def test_too_few_procs(self): size = 3 group = Group() group.add('P', IndepVarComp('x', numpy.ones(size))) group.add('C1', DistribExecComp(['y=2.0*x'], arr_size=size, x=numpy.zeros(size), y=numpy.zeros(size))) group.add('C2', ExecComp(['z=3.0*y'], y=numpy.zeros(size), z=numpy.zeros(size))) prob = Problem(impl=impl) prob.root = group prob.root.ln_solver = LinearGaussSeidel() prob.root.connect('P.x', 'C1.x') prob.root.connect('C1.y', 'C2.y') try: prob.setup(check=False) except Exception as err: self.assertEqual(str(err), "This problem was given 1 MPI processes, " "but it requires between 2 and 2.") else: if MPI: # pragma: no cover self.fail("Exception expected")
def test_conflicting_promoted_state_vars(self): # verify we get an error if we have conflicting promoted state variables root = Group() comp1 = SimpleImplicitComp() comp2 = SimpleImplicitComp() root.add('c1', comp1, promotes=['z']) # promote the state, z root.add('c2', comp2, promotes=['z']) # promote the state, z, again.. BAD prob = Problem(root) with self.assertRaises(RuntimeError) as err: prob.setup(check=False) expected_msg = "Promoted name 'z' matches multiple unknowns: ['c1.z', 'c2.z']" self.assertEqual(str(err.exception), expected_msg)
def setUp(self): '''Initialization function called before every test function''' self.g = Group() self.comp1 = DummyComp() self.comp2 = DummyComp() self.g.add('comp1', self.comp1) self.g.add('comp2', self.comp2) self.p = Problem(root=self.g) self.p.setup()
def test_inlet(self): comp = Inlet() g = Group() g.add('comp', comp) p = Problem(root=g) p.setup() comp.params['ram_recovery'] = 1.0 comp.params['MNexit_des'] = 0.6 comp.params['flow_in:in:W'] = 1.08 comp.params['flow_in:in:Tt'] = 630.75 comp.params['flow_in:in:Pt'] = 0.0272 comp.params['flow_in:in:Mach'] = 1.0 comp.params['design'] = True p.run() TOL = 0.005 assert_rel_error(self, comp.unknowns['flow_out:out:W'], 1.080, TOL) assert_rel_error(self, comp.unknowns['flow_out:out:Pt'], 0.0272, TOL) assert_rel_error(self, comp.unknowns['flow_out:out:Tt'], 630.75, TOL) assert_rel_error(self, comp.unknowns['flow_out:out:rhos'], 0.000098, TOL) assert_rel_error(self, comp.unknowns['flow_out:out:Mach'], 0.6, TOL) assert_rel_error(self, comp.unknowns['flow_out:out:area'], 2230.8, TOL) #check off design comp.params['design'] = False p.run() assert_rel_error(self, comp.unknowns['flow_out:out:W'], 1.080, TOL) assert_rel_error(self, comp.unknowns['flow_out:out:Pt'], 0.0272, TOL) assert_rel_error(self, comp.unknowns['flow_out:out:Tt'], 630.75, TOL) assert_rel_error(self, comp.unknowns['flow_out:out:rhos'], 0.000098, TOL) assert_rel_error(self, comp.unknowns['flow_out:out:Mach'], 0.6, TOL) assert_rel_error(self, comp.unknowns['flow_out:out:area'], 2230.8, TOL) #vary something comp.params['flow_in:in:W'] = 0.9 p.run() assert_rel_error(self, comp.unknowns['flow_out:out:W'], 0.9, TOL) assert_rel_error(self, comp.unknowns['flow_out:out:Pt'], 0.0272, TOL) assert_rel_error(self, comp.unknowns['flow_out:out:Tt'], 630.75, TOL) assert_rel_error(self, comp.unknowns['flow_out:out:Mach'], 0.45955, TOL) assert_rel_error(self, comp.unknowns['flow_out:out:area'], 2230.8, TOL)
def test_multiple_connect(self): root = Group() C1 = root.add("C1", ExecComp("y=x*2.0")) C2 = root.add("C2", ExecComp("y=x*2.0")) C3 = root.add("C3", ExecComp("y=x*2.0")) root.connect("C1.y", ["C2.x", "C3.x"]) root._setup_paths("") params_dict, unknowns_dict = root._setup_variables() # verify we get correct connection information connections = root._get_explicit_connections() expected_connections = {"C2.x": ["C1.y"], "C3.x": ["C1.y"]} self.assertEqual(connections, expected_connections)
def test_array2D(self): group = Group() group.add('x_param', IndepVarComp('x', np.ones((2, 2))), promotes=['*']) group.add('mycomp', ArrayComp2D(), promotes=['x', 'y']) prob = Problem() prob.root = group prob.root.ln_solver = LinearGaussSeidel() prob.setup(check=False) prob.run() J = prob.calc_gradient(['x'], ['y'], mode='fwd', return_format='dict') Jbase = prob.root.mycomp._jacobian_cache diff = np.linalg.norm(J['y']['x'] - Jbase['y', 'x']) assert_rel_error(self, diff, 0.0, 1e-8) J = prob.calc_gradient(['x'], ['y'], mode='rev', return_format='dict') diff = np.linalg.norm(J['y']['x'] - Jbase['y', 'x']) assert_rel_error(self, diff, 0.0, 1e-8)
def test_training_gradient(self): model = Group() ivc = IndepVarComp() mapdata = SampleMap() params = mapdata.param_data outs = mapdata.output_data ivc.add_output('x', np.array([-0.3, 0.7, 1.2])) ivc.add_output('y', np.array([0.14, 0.313, 1.41])) ivc.add_output('z', np.array([-2.11, -1.2, 2.01])) ivc.add_output('f_train', outs[0]['values']) ivc.add_output('g_train', outs[1]['values']) comp = MetaModelStructured(training_data_gradients=True, method='cubic', num_nodes=3) for param in params: comp.add_input(param['name'], param['default'], param['values']) for out in outs: comp.add_output(out['name'], out['default'], out['values']) model.add_subsystem('ivc', ivc, promotes=["*"]) model.add_subsystem('comp', comp, promotes=["*"]) prob = Problem(model) prob.setup() prob.run_model() val0 = np.array([ 50.26787317, 49.76106232, 19.66117913]) val1 = np.array([-32.62094041, -31.67449135, -27.46959668]) tol = 1e-5 assert_rel_error(self, prob['f'], val0, tol) assert_rel_error(self, prob['g'], val1, tol) self.run_and_check_derivs(prob)
def test_two_simple(self): group = Group() group.add('x_param', IndepVarComp('x', 1.0)) group.add('comp1', ExecComp(['y=2.0*x'])) group.add('comp2', ExecComp(['z=3.0*y'])) prob = Problem() prob.root = group prob.root.ln_solver = LinearGaussSeidel() prob.root.connect('x_param.x', 'comp1.x') prob.root.connect('comp1.y', 'comp2.y') prob.setup(check=False) prob.run() J = prob.calc_gradient(['x_param.x'], ['comp2.z'], mode='fwd', return_format='dict') assert_rel_error(self, J['comp2.z']['x_param.x'][0][0], 6.0, 1e-6) J = prob.calc_gradient(['x_param.x'], ['comp2.z'], mode='rev', return_format='dict') assert_rel_error(self, J['comp2.z']['x_param.x'][0][0], 6.0, 1e-6)
def test_calc_gradient_interface_errors(self): root = Group() prob = Problem(root=root) root.add('comp', ExecComp('y=x*2.0')) try: prob.calc_gradient(['comp.x'], ['comp.y'], mode='junk') except Exception as error: msg = "mode must be 'auto', 'fwd', 'rev', or 'fd'" self.assertEqual(text_type(error), msg) else: self.fail("Error expected") try: prob.calc_gradient(['comp.x'], ['comp.y'], return_format='junk') except Exception as error: msg = "return_format must be 'array' or 'dict'" self.assertEqual(text_type(error), msg) else: self.fail("Error expected")