def test_nested_2Darray_simul_element_and_full_connection2(self): # Slightly different config top = Assembly() top.add('nest', Assembly()) top.nest.add('comp1', ArrayComp2D()) top.nest.add('comp2', ArrayComp2D()) top.driver.gradient_options.lin_solver = 'petsc_ksp' top.nest.driver.gradient_options.lin_solver = 'petsc_ksp' top.nest.driver.workflow.add(['comp1', 'comp2']) top.nest.connect('comp1.y', 'comp2.x') top.nest.create_passthrough('comp1.x') top.nest.create_passthrough('comp1.y') top.nest.add('yy', Array(iotype='out')) top.nest.connect('comp2.y', 'yy') top.add('driver', SimpleDriver()) top.driver.workflow.add(['nest']) top.driver.add_parameter('nest.x[0][0]', low=-10, high=10) top.driver.add_objective('nest.yy[0][0]') top.driver.add_constraint('nest.y[0][1] < 0') top.run() J = top.driver.calc_gradient(mode='forward') assert_rel_error(self, J[0, 0], 24.0, .000001) assert_rel_error(self, J[1, 0], 4.0, .000001) J = top.driver.calc_gradient(mode='adjoint') assert_rel_error(self, J[0, 0], 24.0, .000001) assert_rel_error(self, J[1, 0], 4.0, .000001) J = top.driver.calc_gradient(mode='fd') assert_rel_error(self, J[0, 0], 24.0, .000001) assert_rel_error(self, J[1, 0], 4.0, .000001)
def test_tracing(self): # Check tracing of iteration coordinates. top = Assembly() comp = top.add('comp1', Dummy()) top.add('driverA', Driver()) comp = top.add('comp2', Dummy()) top.add('driverB', Driver()) sub = top.add('subassy', Assembly()) comp = sub.add('comp3', Dummy()) sub.driver.workflow.add('comp3') top.driver.workflow = SequentialWorkflow() top.driver.workflow.add(('comp1', 'driverA', 'driverB')) top.driverA.workflow.add(('comp1', 'comp2')) top.driverB.workflow.add(('comp2', 'subassy')) trace_out = cStringIO.StringIO() enable_trace(trace_out) top.run() expected = """\ 1-comp1 1-driverA.1-comp1 1-driverA.1-comp2 1-driverB.1-comp2 1-driverB.1-subassy.1-comp3 """ self.assertEqual(trace_out.getvalue(), expected) disable_trace() top.run() self.assertEqual(trace_out.getvalue(), expected)
class GeomTestCase(unittest.TestCase): def setUp(self): """this setup function will be called before each test in this class""" self.top = Assembly() self.top.add('g1', GeoSource()) self.top.add('g2', GeoSink()) self.top.connect('g1.g_out', 'g2.g_inp') self.top.driver.workflow.add(['g1', 'g2']) def tearDown(self): """this teardown function will be called after each test""" self.top = None def testGeom(self): self.top.run() self.assertEqual(1, self.top.g2.g_inp.get_tessellation()) try: self.top.g2.g_extra = "hey" except TypeError as err: msg = "g2 (1-g2): object g_extra of type <type 'str'> must provide interface 'IStaticGeometry'" self.assertEqual(str(err), msg) else: self.fail("exception expected")
def test_linearGS_simul_element_and_full_connection(self): # Added because of a bug with array slices for Linear GS top = Assembly() top.add('comp1', ArrayComp2D()) top.add('comp2', ArrayComp2D()) top.add('driver', SimpleDriver()) top.driver.workflow.add(['comp1', 'comp2']) top.connect('comp1.y', 'comp2.x') top.driver.add_parameter('comp1.x[0][0]', low=-10, high=10) top.driver.add_objective('comp1.y[0][0]') top.driver.add_constraint('comp2.y[0][1] < 0') top.driver.gradient_options.lin_solver = 'linear_gs' top.driver.gradient_options.maxiter = 1 top.run() J = top.driver.calc_gradient(mode='forward') assert_rel_error(self, J[0, 0], 2.0, .000001) assert_rel_error(self, J[1, 0], 39.0, .000001) J = top.driver.calc_gradient(mode='adjoint') assert_rel_error(self, J[0, 0], 2.0, .000001) assert_rel_error(self, J[1, 0], 39.0, .000001)
def test_super_simple_backward(self): model = Assembly() model.add('driver', DistributionCaseDriver()) model.add('driven', SimpleComponent()) model.driver.workflow.add('driven') model.driver.distribution_generator = FiniteDifferenceGenerator(model.driver) model.driver.add_response('driven.y') model.driver.add_parameter("driven.x", low=-10., high=10., fd_step=0.1) model.driver.distribution_generator.form = "BACKWARD" model.driver.distribution_generator.order = 2 model.run() x = model.driver.case_inputs.driven.x y = model.driver.case_outputs.driven.y self.assertAlmostEqual(x[0], 1.0, places=6) self.assertAlmostEqual(y[0], 2.0, places=6) self.assertAlmostEqual(x[1], 0.8, places=6) self.assertAlmostEqual(y[1], 1.6, places=6) self.assertAlmostEqual(x[2], 0.9, places=6) self.assertAlmostEqual(y[2], 1.8, places=6)
def test_scid2(self): logging.debug('') logging.debug('test_simplecid') top = Assembly() top.add('generator', Generator()) cid = top.add('cid', SimpleCaseIterDriver()) top.add('driven', DrivenComponent()) top.add('verifier', Verifier()) top.driver.workflow.add(('generator', 'cid', 'verifier')) cid.workflow.add('driven') cid.add_parameter('driven.x') cid.add_parameter('driven.y') cid.add_response('driven.rosen_suzuki') cid.add_response('driven.sum_y') top.connect('generator.x', 'cid.case_inputs.driven.x') top.connect('generator.y', 'cid.case_inputs.driven.y') top.connect('generator.x', 'verifier.x') top.connect('generator.y', 'verifier.y') top.connect('cid.case_outputs.driven.rosen_suzuki', 'verifier.rosen_suzuki') top.connect('cid.case_outputs.driven.sum_y', 'verifier.sum_y') top.run()
def test_vtree(self): top = Assembly() sub = top.add('sub', Assembly()) sub.add('comp', LoadsComp()) sub.driver.workflow.add('comp') sub.create_passthrough('comp.loads_in') sub.create_passthrough('comp.loads_out') top.driver.workflow.add('sub') jsonfile = os.path.join(self.tempdir, 'test_vtree.json') old_json_file = os.path.join(os.path.dirname(__file__), 'vtree.json') top.recorders = [JSONCaseRecorder(jsonfile)] loads = Loads() loads.Fx = [1, 2, 3] loads.Fy = [4, 5, 6] loads.Fz = [7, 8, 9] arr = LoadsArray() arr.loads = [loads] top.sub.loads_in = arr top.run() cdsnew = CaseDataset(jsonfile, 'json') cdsold = CaseDataset(old_json_file, 'json') cdsold.data.vars('sub.comp.loads_out').fetch( )[0][0]['loads'][0]['Fx'] == cdsnew.data.vars( 'sub.comp.loads_out').fetch()[0][0]['loads'][0]['Fx'] cdsold.data.vars('sub.comp.loads_out').fetch( )[1][0]['loads'][0]['Fz'] == cdsnew.data.vars( 'sub.comp.loads_out').fetch()[1][0]['loads'][0]['Fz']
def test_super_simple_forward(self): model = Assembly() model.add("driver", DistributionCaseDriver()) model.add("driven", SimpleComponent()) model.driver.workflow.add("driven") # Forward model.driver.distribution_generator = FiniteDifferenceGenerator(model.driver) model.driver.case_outputs = ["driven.y"] model.driver.add_parameter("driven.x", low=-10.0, high=10.0, fd_step=0.1) results = ListCaseRecorder() model.driver.recorders = [results] model.driver.distribution_generator.form = "FORWARD" model.driver.distribution_generator.order = 2 model.run() self.assertAlmostEqual(results.cases[0]["driven.x"], 1.0, places=6) self.assertAlmostEqual(results.cases[0]["driven.y"], 2.0, places=6) self.assertAlmostEqual(results.cases[1]["driven.x"], 1.1, places=6) self.assertAlmostEqual(results.cases[1]["driven.y"], 2.2, places=6) self.assertAlmostEqual(results.cases[2]["driven.x"], 1.2, places=6) self.assertAlmostEqual(results.cases[2]["driven.y"], 2.4, places=6)
def test_super_simple_backward(self): model = Assembly() model.add('driver', DistributionCaseDriver()) model.add('driven', SimpleComponent()) model.driver.workflow.add('driven') model.driver.distribution_generator = FiniteDifferenceGenerator(model.driver) model.driver.case_outputs = ['driven.y'] model.driver.add_parameter("driven.x", low=-10., high=10., fd_step = 0.1 ) results = ListCaseRecorder() model.driver.recorders = [results] model.driver.distribution_generator.form = "BACKWARD" model.driver.distribution_generator.order = 2 model.run() self.assertAlmostEqual( results.cases[0][ 'driven.x' ], 1.0, places = 6 ) self.assertAlmostEqual( results.cases[0][ 'driven.y' ], 2.0, places = 6 ) self.assertAlmostEqual( results.cases[1][ 'driven.x' ], 0.8, places = 6 ) self.assertAlmostEqual( results.cases[1][ 'driven.y' ], 1.6, places = 6 ) self.assertAlmostEqual( results.cases[2][ 'driven.x' ], 0.9, places = 6 ) self.assertAlmostEqual( results.cases[2][ 'driven.y' ], 1.8, places = 6 )
def test_vtree(self): top = Assembly() sub = top.add('sub', Assembly()) sub.add('comp', LoadsComp()) sub.driver.workflow.add('comp') sub.create_passthrough('comp.loads_in') sub.create_passthrough('comp.loads_out') top.driver.workflow.add('sub') jsonfile = os.path.join(self.tempdir, 'test_vtree.json') old_json_file = os.path.join(os.path.dirname(__file__), 'vtree.json') top.recorders = [JSONCaseRecorder(jsonfile)] loads = Loads() loads.Fx = [1, 2, 3] loads.Fy = [4, 5, 6] loads.Fz = [7, 8, 9] arr = LoadsArray() arr.loads = [loads] top.sub.loads_in = arr top.run() cdsnew = CaseDataset(jsonfile, 'json') cdsold = CaseDataset(old_json_file, 'json') cdsold.data.vars('sub.comp.loads_out').fetch()[0][0]['loads'][0]['Fx'] == cdsnew.data.vars('sub.comp.loads_out').fetch()[0][0]['loads'][0]['Fx'] cdsold.data.vars('sub.comp.loads_out').fetch()[1][0]['loads'][0]['Fz'] == cdsnew.data.vars('sub.comp.loads_out').fetch()[1][0]['loads'][0]['Fz']
def test_vtree(self): top = Assembly() sub = top.add('sub', Assembly()) sub.add('comp', LoadsComp()) sub.driver.workflow.add('comp') sub.create_passthrough('comp.loads_in') sub.create_passthrough('comp.loads_out') top.driver.workflow.add('sub') sout = StringIO() top.recorders = [JSONCaseRecorder(sout)] loads = Loads() loads.Fx = [1, 2, 3] loads.Fy = [4, 5, 6] loads.Fz = [7, 8, 9] arr = LoadsArray() arr.loads = [loads] top.sub.loads_in = arr top.run() # with open('vtree.new', 'w') as out: # out.write(sout.getvalue()) self.verify(sout, 'vtree.json')
def test_scid(self): # Record tree of cases via SimpleCaseIterDriver. top = Assembly() top.recorders = [ListCaseRecorder()] top.add('driver2', SCIDriver(3, 'comp2')) top.add('comp2', CaseComponent()) top.driver2.workflow.add('comp2') top.add('driver1', SCIDriver(2, 'comp1')) top.add('comp1', CaseComponent()) top.driver1.workflow.add(['comp1', 'driver2']) top.driver.workflow.add('driver1') top.run() print print 'Forest:' roots = CaseTreeNode.sort(top.recorders[0].get_iterator()) for root in roots: root.dump(1) print print 'Iternames:' for root in roots: for name in root.iternames(): print ' ', name expected = [ '1', '1-1.1', '1-1.1-2.1', '1-1.1-2.2', '1-1.1-2.3', '1-1.2', '1-1.2-2.1', '1-1.2-2.2', '1-1.2-2.3' ] for i, name in enumerate(roots[0].iternames()): self.assertEqual(name, expected[i])
def test_circular_dependency(self): self.asm.connect('comp1.rout', 'comp2.r') # Cyclic graphs are permitted in declaration. self.asm.connect('comp2.rout', 'comp1.r') # Unconnected added twice shouldn't cause exception. asm = Assembly() asm.add('a', Simple()) asm.add('b', Simple()) dup1 = asm.add('dup1', Simple()) dup2 = asm.add('dup2', Simple()) self.assertEqual(dup1.exec_count, 0) self.assertEqual(dup2.exec_count, 0) sequence = ['dup1', 'a', 'dup2', 'dup1', 'b', 'dup1', 'dup2'] asm.driver.workflow.add(sequence) self.assertEqual([comp.name for comp in asm.driver.workflow], sequence) asm.run() self.assertEqual(dup1.exec_count, 3) self.assertEqual(dup2.exec_count, 2) asm = Assembly() asm.add('a', Simple()) asm.add('b', Simple()) dup1 = asm.add('dup1', Simple()) dup2 = asm.add('dup2', Simple()) self.assertEqual(dup1.exec_count, 0) self.assertEqual(dup2.exec_count, 0) sequence = ['dup1', 'a', 'dup2', 'dup1', 'b', 'dup1', 'dup2'] asm.driver.workflow.add(sequence) self.assertEqual([comp.name for comp in asm.driver.workflow], sequence) asm.run() self.assertEqual(dup1.exec_count, 3) self.assertEqual(dup2.exec_count, 2)
def test_super_simple_forward(self): model = Assembly() model.add('driver', DistributionCaseDriver()) model.add('driven', SimpleComponent()) model.driver.workflow.add('driven') # Forward model.driver.distribution_generator = FiniteDifferenceGenerator( model.driver) model.driver.add_response('driven.y') model.driver.add_parameter("driven.x", low=-10., high=10., fd_step=0.1) model.driver.distribution_generator.form = "FORWARD" model.driver.distribution_generator.order = 2 model.run() x = model.driver.case_inputs.driven.x y = model.driver.case_outputs.driven.y self.assertAlmostEqual(x[0], 1.0, places=6) self.assertAlmostEqual(y[0], 2.0, places=6) self.assertAlmostEqual(x[1], 1.1, places=6) self.assertAlmostEqual(y[1], 2.2, places=6) self.assertAlmostEqual(x[2], 1.2, places=6) self.assertAlmostEqual(y[2], 2.4, places=6)
class GeomTestCase(unittest.TestCase): def setUp(self): """this setup function will be called before each test in this class""" self.top = Assembly() self.top.add('g1', GeoSource()) self.top.add('g2', GeoSink()) self.top.connect('g1.g_out', 'g2.g_inp') self.top.driver.workflow.add(['g1', 'g2']) def tearDown(self): """this teardown function will be called after each test""" self.top = None def testGeom(self): self.top.run() self.assertEqual(1, self.top.g2.g_inp.get_tessellation()) try: self.top.g2.g_extra = "hey" except TypeError as err: msg = "g2 (1-2): g_extra must provide interface 'IStaticGeometry'" self.assertEqual(str(err), msg) else: self.fail("exception expected")
def lofted_blade_shape_example(): top = Assembly() configure_bladesurface(top, planform_nC=6) # load the planform file top.pf_splines.pfIn = read_blade_planform('data/DTU_10MW_RWT_blade_axis_prebend.dat') top.blade_length = 86.366 top.span_ni = 50 print 'planform variables: ', top.pf_splines.pfOut.list_vars() b = top.blade_surface # distribute 200 points evenly along the airfoil sections b.chord_ni = 200 # load the airfoil shapes defining the blade for f in ['data/ffaw3241.dat', 'data/ffaw3301.dat', 'data/ffaw3360.dat', 'data/ffaw3480.dat' , 'data/tc72.dat' , 'data/cylinder.dat']: b.base_airfoils.append(np.loadtxt(f)) b.blend_var = np.array([0.241, 0.301, 0.36, 0.48, 0.72, 1.]) top.run() pf = top.pf_splines.pfOut plt.figure() plt.title('chord') plt.plot(pf.s, pf.chord) plt.savefig('chord.eps') plt.figure() plt.title('twist') plt.plot(pf.s, pf.rot_z) plt.savefig('twist.eps') plt.figure() plt.title('relative thickness') plt.plot(pf.s, pf.rthick) plt.savefig('rthick.eps') plt.figure() plt.title('pitch axis aft leading edge') plt.plot(pf.s, pf.p_le) plt.savefig('p_le.eps') plt.figure() plt.axis('equal') for i in range(b.span_ni): plt.plot(b.surfout.surface[:, i, 0], b.surfout.surface[:, i, 1]) plt.savefig('lofted_blade.eps') return top
def lofted_blade_shape_example(): top = Assembly() configure_bladesurface(top, 'data/DTU_10MW_RWT_blade_axis_prebend.dat', planform_nC=6) # load the planform file top.blade_length = 86.366 top.span_ni = 50 print 'planform variables: ', top.pf_splines.pfOut.list_vars() b = top.blade_surface # distribute 200 points evenly along the airfoil sections b.chord_ni = 200 # load the airfoil shapes defining the blade for f in ['data/ffaw3241.dat', 'data/ffaw3301.dat', 'data/ffaw3360.dat', 'data/ffaw3480.dat' , 'data/tc72.dat' , 'data/cylinder.dat']: b.base_airfoils.append(np.loadtxt(f)) b.blend_var = np.array([0.241, 0.301, 0.36, 0.48, 0.72, 1.]) top.run() pf = top.pf_splines.pfOut plt.figure() plt.title('chord') plt.plot(pf.s, pf.chord) plt.savefig('chord.eps') plt.figure() plt.title('twist') plt.plot(pf.s, pf.rot_z) plt.savefig('twist.eps') plt.figure() plt.title('relative thickness') plt.plot(pf.s, pf.rthick) plt.savefig('rthick.eps') plt.figure() plt.title('pitch axis aft leading edge') plt.plot(pf.s, pf.p_le) plt.savefig('p_le.eps') plt.figure() plt.axis('equal') for i in range(b.span_ni): plt.plot(b.surfout.surface[:, i, 0], b.surfout.surface[:, i, 1]) plt.savefig('lofted_blade.eps') plt.savefig('lofted_blade.png') return top
def test_smart_low_high_array_param(self): top = Assembly() top.add('paraboloid', ArrayParaboloid()) driver = top.add('driver', SimpleDriver()) driver.add_objective('paraboloid.f_x') driver.add_parameter('paraboloid.x', low=[-100, -99], high=[100, 99]) driver.workflow.add('paraboloid') top.run() J = top.driver.calc_gradient()
def test_smart_low_high_array_param(self): top = Assembly() top.add('paraboloid', ArrayParaboloid()) driver = top.add('driver', SimpleDriver()) driver.add_objective('paraboloid.f_x') driver.add_parameter('paraboloid.x', low=[-100, -99], high=[100, 99]) driver.workflow.add('paraboloid') top.run() J = top.driver.workflow.calc_gradient()
def test_scaler_array_expression(self): model = Assembly() model.add('sub', SubAsmb()) model.driver.workflow.add('sub') model.run() J = model.driver.workflow.calc_gradient(inputs=['sub.x', 'sub.y'], outputs=['sub.z']) assert_rel_error(self, J[0, 0], 10.0, .001) assert_rel_error(self, J[0, 1], 10.0, .001) assert_rel_error(self, J[0, 2], 20.0, .001)
def test_scaler_array_expression(self): model = Assembly() model.add('sub', SubAsmb()) model.driver.workflow.add('sub') model.run() J = model.driver.workflow.calc_gradient(inputs=['sub.x', 'sub.y'], outputs=['sub.z']) assert_rel_error(self, J[0,0], 10.0, .001) assert_rel_error(self, J[0,1], 10.0, .001) assert_rel_error(self, J[0,2], 20.0, .001)
def test_multiconnect(self): top = Assembly() for name in ('m1', 'm2', 'm3'): top.add(name, Multiplier()) top.driver.workflow.add(name) top.connect('m1.rval_out', ('m2.mult', 'm3.mult')) top.m1.rval_in = 1. top.m2.rval_in = 3. top.m3.rval_in = 4. top.run() self.assertEqual(top.m2.rval_out, 4.5) self.assertEqual(top.m3.rval_out, 6.)
def test_multiconnect(self): top = Assembly() for name in ("m1", "m2", "m3"): top.add(name, Multiplier()) top.driver.workflow.add(name) top.connect("m1.rval_out", ("m2.mult", "m3.mult")) top.m1.rval_in = 1.0 top.m2.rval_in = 3.0 top.m3.rval_in = 4.0 top.run() self.assertEqual(top.m2.rval_out, 4.5) self.assertEqual(top.m3.rval_out, 6.0)
def test_workflow_itername(self): # top # comp1 # driverA # comp1 # comp2 # driverB # comp2 # subassy # comp3 top = Assembly() top.add('comp1', Basic_Component()) top.add('driverA', Run_N(4)) top.add('comp2', Basic_Component()) top.add('driverB', Run_N(3)) sub = top.add('subassy', Assembly()) sub.add('comp3', Basic_Component()) sub.driver.workflow.add('comp3') top.driver.workflow.add(('comp1', 'driverA', 'driverB')) sout = StringIO.StringIO() top.recorders = [DumpCaseRecorder(sout)] top.driverA.workflow.add(('comp1', 'comp2')) top.driverB.workflow.add(('comp2', 'subassy')) top.run() expected = [ 'driverA.workflow.itername: 1-driverA.1', 'driverA.workflow.itername: 1-driverA.2', 'driverA.workflow.itername: 1-driverA.3', 'driverA.workflow.itername: 1-driverA.4', 'driverA.workflow.itername: 1-driverA.5', 'subassy.driver.workflow.itername: 1-driverB.1-subassy.1', 'driverB.workflow.itername: 1-driverB.1', 'subassy.driver.workflow.itername: 1-driverB.2-subassy.1', 'driverB.workflow.itername: 1-driverB.2', 'subassy.driver.workflow.itername: 1-driverB.3-subassy.1', 'driverB.workflow.itername: 1-driverB.3', 'subassy.driver.workflow.itername: 1-driverB.4-subassy.1', 'driverB.workflow.itername: 1-driverB.4', 'driver.workflow.itername: 1' ] lines = [ l.strip() for l in sout.getvalue().split('\n') if 'workflow.itername' in l ] for i, line in enumerate(lines): self.assertEqual(line, expected[i])
def test_workflow_itername(self): # top # comp1 # driverA # comp1 # comp2 # driverB # comp2 # subassy # comp3 top = Assembly() top.add('comp1', Basic_Component()) top.add('driverA', Run_N(4)) top.add('comp2', Basic_Component()) top.add('driverB', Run_N(3)) sub = top.add('subassy', Assembly()) sout_sub = StringIO.StringIO() sub.driver.recorders = [DumpCaseRecorder(sout_sub)] sub.add('comp3', Basic_Component()) sub.driver.workflow.add('comp3') top.driver.workflow.add(('comp1', 'driverA', 'driverB')) sout = StringIO.StringIO() top.driver.recorders = [DumpCaseRecorder(sout)] top.driverA.workflow.add(('comp1', 'comp2')) soutA = StringIO.StringIO() top.driverA.recorders = [DumpCaseRecorder(soutA)] top.driverB.workflow.add(('comp2', 'subassy')) soutB = StringIO.StringIO() top.driverB.recorders = [DumpCaseRecorder(soutB)] top.run() lines = [l.strip() for l in sout.getvalue().split('\n') if 'itername' in l] linesA = [l.strip() for l in soutA.getvalue().split('\n') if 'itername' in l] linesB = [l.strip() for l in soutB.getvalue().split('\n') if 'itername' in l] lines_sub = [l.strip() for l in sout_sub.getvalue().split('\n') if 'itername' in l] self.assertEqual(lines, ['driver.workflow.itername: 1']) self.assertEqual(linesA, ['driverA.workflow.itername: 1-1.1', 'driverA.workflow.itername: 1-1.2', 'driverA.workflow.itername: 1-1.3', 'driverA.workflow.itername: 1-1.4', 'driverA.workflow.itername: 1-1.5']) self.assertEqual(linesB, ['driverB.workflow.itername: 1-2.1', 'driverB.workflow.itername: 1-2.2', 'driverB.workflow.itername: 1-2.3', 'driverB.workflow.itername: 1-2.4']) self.assertEqual(lines_sub, ['driver.workflow.itername: 1-2.1-2.1'])
def test_workflow_itername(self): # top # comp1 # driverA # comp1 # comp2 # driverB # comp2 # subassy # comp3 top = Assembly() top.add('comp1', Basic_Component()) top.add('driverA', Run_N(4)) top.add('comp2', Basic_Component()) top.add('driverB', Run_N(3)) sub = top.add('subassy', Assembly()) sub.add('comp3', Basic_Component()) sub.driver.workflow.add('comp3') top.driver.workflow.add(('comp1', 'driverA', 'driverB')) sout = StringIO.StringIO() top.recorders = [DumpCaseRecorder(sout)] top.driverA.workflow.add(('comp1', 'comp2')) top.driverB.workflow.add(('comp2', 'subassy')) top.run() expected = [ 'driverA.workflow.itername: 1-driverA.1', 'driverA.workflow.itername: 1-driverA.2', 'driverA.workflow.itername: 1-driverA.3', 'driverA.workflow.itername: 1-driverA.4', 'driverA.workflow.itername: 1-driverA.5', 'subassy.driver.workflow.itername: 1-driverB.1-subassy.1', 'driverB.workflow.itername: 1-driverB.1', 'subassy.driver.workflow.itername: 1-driverB.2-subassy.1', 'driverB.workflow.itername: 1-driverB.2', 'subassy.driver.workflow.itername: 1-driverB.3-subassy.1', 'driverB.workflow.itername: 1-driverB.3', 'subassy.driver.workflow.itername: 1-driverB.4-subassy.1', 'driverB.workflow.itername: 1-driverB.4', 'driver.workflow.itername: 1' ] lines = [l.strip() for l in sout.getvalue().split('\n') if 'workflow.itername' in l] for i, line in enumerate(lines): self.assertEqual(line, expected[i])
def test_comp_error(self): a = Assembly() a.add('m',MetaModel()) a.m.default_surrogate = KrigingSurrogate() a.m.model = DummyError() a.m.train_next = True a.driver.workflow.add('m') try: a.run() except RuntimeError as err: self.assertEqual("m.model: Test Error",str(err)) else: self.fail("RuntimeError expected")
def test_comp_error(self): a = Assembly() a.add('m', MetaModel()) a.m.surrogate = {'default': KrigingSurrogate()} a.m.model = DummyError() a.m.train_next = True a.driver.workflow.add('m') try: a.run() except RuntimeError as err: self.assertEqual("m.model: Test Error", str(err)) else: self.fail("RuntimeError expected")
def test_connections(self): logging.debug('') logging.debug('test_connections') top = Assembly() top.add('generator', Generator()) top.add('cid', CaseIteratorDriver()) top.add('driven', DrivenComponent()) top.add('verifier', Verifier()) top.driver.workflow.add(('generator', 'cid', 'verifier')) top.cid.workflow.add('driven') top.connect('generator.cases', 'cid.iterator') top.connect('cid.evaluated', 'verifier.cases') top.run()
def test_casetree(self): # Record tree of cases via workflow. top = Assembly() top.recorders = [DumbRecorder()] top.add('driver2', CaseDriver(3)) top.add('comp2', CaseComponent()) top.driver2.workflow.add('comp2') top.driver2.add_parameter('comp2.x', low=0, high=10) top.driver2.add_objective('comp2.y') top.add('driver1', CaseDriver(2)) top.add('comp1', CaseComponent()) top.driver1.add_parameter('comp1.x', low=0, high=10) top.driver1.add_objective('comp1.y') top.driver1.workflow.add(['comp1', 'driver2']) top.driver.workflow.add('driver1') top.run() print print 'Forest:' roots = CaseTreeNode.sort(top.recorders[0].get_iterator()) for root in roots: root.dump(1) print print 'Iternames:' for root in roots: for name in root.iternames(): print ' ', name expected = [ '1', '1-driver1.1', '1-driver1.1-driver2.1', '1-driver1.1-driver2.2', '1-driver1.1-driver2.3', '1-driver1.2', '1-driver1.2-driver2.1', '1-driver1.2-driver2.2', '1-driver1.2-driver2.3' ] for i, name in enumerate(roots[0].iternames()): self.assertEqual(name, expected[i])
def test_connections(self): logging.debug('') logging.debug('test_connections') top = Assembly() top.add('generator', Generator()) top.add('cid', CaseIteratorDriver()) top.add('driven', DrivenComponent()) top.add('verifier', Verifier()) top.driver.workflow.add(('generator', 'cid', 'verifier')) top.cid.workflow.add('driven') top.cid.printvars = ['driven.extra'] top.connect('generator.cases', 'cid.iterator') top.connect('cid.evaluated', 'verifier.cases') top.run()
def test_connections(self): logging.debug("") logging.debug("test_connections") top = Assembly() top.add("generator", Generator()) top.add("cid", CaseIteratorDriver()) top.add("driven", DrivenComponent()) top.add("verifier", Verifier()) top.driver.workflow.add(("generator", "cid", "verifier")) top.cid.workflow.add("driven") top.cid.printvars = ["driven.extra"] top.connect("generator.cases", "cid.iterator") top.connect("cid.evaluated", "verifier.cases") top.run()
def test_invalid_case_outputs(self): model = Assembly() model.add('driver', DistributionCaseDriver()) model.add('driven', SimpleComponent()) model.driver.workflow.add('driven') model.driver.distribution_generator = FiniteDifferenceGenerator(model.driver) model.driver.case_outputs = ['driven.invalid'] model.driver.add_parameter("driven.x", low=-10., high=10., fd_step = 0.1 ) model.driver.error_policy = 'RETRY' results = ListCaseRecorder() model.driver.recorders = [results] model.driver.distribution_generator.form = "FORWARD" model.driver.distribution_generator.order = 2 model.run() self.assertEqual(results.cases[0].items()[1][1], _Missing )
def test_circular_dependency(self): self.asm.connect('comp1.rout', 'comp2.r') # Cyclic graphs are permitted in declaration. self.asm.connect('comp2.rout', 'comp1.r') # duplicate entries in workflow should cause exception. asm = Assembly() asm.add('a', Simple()) asm.add('b', Simple()) dup1 = asm.add('dup1', Simple()) dup2 = asm.add('dup2', Simple()) self.assertEqual(dup1.exec_count, 0) self.assertEqual(dup2.exec_count, 0) sequence = ['dup1', 'a', 'dup2', 'dup1', 'b', 'dup1', 'dup2'] asm.driver.workflow.add(sequence) try: asm.run() except RuntimeError as err: self.assertEqual(str(err), "driver workflow has duplicate entries: ['dup1', 'dup2']")
def test_smart_low_high(self): top = Assembly() top.add('comp', MyComp()) driver = top.add('driver', SimpleDriver()) top.comp.add('x1', Float(1.0, iotype='in', low=-1.0, high=1.0)) driver.add_objective('comp.y') driver.add_parameter('comp.x1', low=-1.0, high=1.0) driver.workflow.add('comp') top.driver.gradient_options.fd_form = 'central' top.driver.gradient_options.fd_step = 0.1 top.comp.x1 = -0.95 top.run() J = top.driver.calc_gradient() assert_rel_error(self, J[0, 0], -3.6, 0.001) top.comp.x1 = 0.95 top.run() J = top.driver.calc_gradient() assert_rel_error(self, J[0, 0], 3.6, 0.001)
def test_smart_low_high(self): top = Assembly() top.add('comp', MyComp()) driver = top.add('driver', SimpleDriver()) top.comp.add('x1', Float(1.0, iotype='in', low=-1.0, high=1.0)) driver.add_objective('comp.y') driver.add_parameter('comp.x1', low=-1.0, high=1.0) driver.workflow.add('comp') top.driver.gradient_options.fd_form = 'central' top.driver.gradient_options.fd_step = 0.1 top.comp.x1 = -0.95 top.run() J = top.driver.workflow.calc_gradient() assert_rel_error(self, J[0, 0], -3.6, 0.001) top.comp.x1 = 0.95 top.run() J = top.driver.workflow.calc_gradient() assert_rel_error(self, J[0, 0], 3.6, 0.001)
def test_tracing(self): # Check tracing of iteration coordinates. top = Assembly() comp = top.add("comp1", Dummy()) comp.force_execute = True top.add("driverA", Driver()) comp = top.add("comp2", Dummy()) comp.force_execute = True top.add("driverB", Driver()) sub = top.add("subassy", Assembly()) sub.force_execute = True comp = sub.add("comp3", Dummy()) comp.force_execute = True sub.driver.workflow.add("comp3") top.driver.workflow = SequentialWorkflow() top.driver.workflow.add(("comp1", "driverA", "driverB")) top.driverA.workflow.add(("comp1", "comp2")) top.driverB.workflow.add(("comp2", "subassy")) trace_out = cStringIO.StringIO() enable_trace(trace_out) top.run() expected = """\ 1-1 1-2.1-1 1-2.1-2 1-3.1-1 1-3.1-2.1-1 """ self.assertEqual(trace_out.getvalue(), expected) disable_trace() top.run() self.assertEqual(trace_out.getvalue(), expected)
class ArrayTest(unittest.TestCase): def setUp(self): self.top = Assembly() self.top.add('driver', MyDriver()) self.top.add('comp', ArrayComp()) self.top.driver.workflow.add('comp') def test_basic(self): top = self.top comp = top.comp driver = top.driver comp.x1d = [1, 2, 3] comp.x2d = [[1, 2, 3], [4, 5, 6]] top.run() self.assertEqual(comp.fx1d, 6.) self.assertEqual(list(comp.fx2d), [6., 15.]) code = "driver.add_parameter('comp.x1d')" assert_raises(self, code, globals(), locals(), ValueError, "driver: Trying to add parameter 'comp.x1d', but no" " lower limit was found and no 'low' argument was given." " One or the other must be specified.") code = "driver.add_parameter('comp.x1d', low=-10)" assert_raises(self, code, globals(), locals(), ValueError, "driver: Trying to add parameter 'comp.x1d', but no" " upper limit was found and no 'high' argument was given." " One or the other must be specified.") driver.add_parameter('comp.x1d', low=-10, high=10, start=1) code = "driver.add_parameter('comp.x2d')" assert_raises(self, code, globals(), locals(), ValueError, "driver: Trying to add parameter 'comp.x2d', but no" " lower limit was found and no 'low' argument was given." " One or the other must be specified.") code = "driver.add_parameter('comp.x2d', low=-10)" assert_raises(self, code, globals(), locals(), ValueError, "driver: Trying to add parameter 'comp.x2d', but no" " upper limit was found and no 'high' argument was given." " One or the other must be specified.") driver.add_parameter('comp.x2d', low=-10, high=10, start=2) top.run() comp.x1d = [1, 2, 3] comp.x2d = [[1, 2, 3], [4, 5, 6]] targets = driver.list_param_targets() self.assertEqual(targets, ['comp.x1d', 'comp.x2d']) targets = driver.list_param_group_targets() self.assertEqual(targets, [('comp.x1d',), ('comp.x2d',)]) self.assertEqual(list(comp.x1d), [1, 2, 3]) self.assertEqual([list(row) for row in comp.x2d[:]], [[1, 2, 3], [4, 5, 6]]) driver.init_parameters() var = driver.workflow._system.vec['u']['comp.x1d'] self.assertEqual(list(var), [1, 1, 1]) var = driver.workflow._system.vec['u']['comp.x2d'] self.assertEqual(list(var), [2, 2, 2, 2, 2, 2]) driver.set_parameter_by_name('comp.x1d', 3) var = driver.workflow._system.vec['u']['comp.x1d'] self.assertEqual(list(var), [3, 3, 3]) driver.set_parameter_by_name('comp.x1d', array([4, 5, 6])) var = driver.workflow._system.vec['u']['comp.x1d'] self.assertEqual(list(var), [4, 5, 6]) driver.set_parameter_by_name('comp.x2d', 4) var = driver.workflow._system.vec['u']['comp.x2d'] self.assertEqual(list(var), [4, 4, 4, 4, 4, 4]) driver.set_parameter_by_name('comp.x2d', array([[5, 6, 7], [8, 9, 0]])) var = driver.workflow._system.vec['u']['comp.x2d'] self.assertEqual(list(var), [5, 6, 7, 8, 9, 0]) driver.set_parameters([7, 8, 9, 1, 2, 3, 4, 5, 6]) var = driver.workflow._system.vec['u']['comp.x1d'] self.assertEqual(list(var), [7, 8, 9]) var = driver.workflow._system.vec['u']['comp.x2d'] self.assertEqual(list(var), [1, 2, 3, 4, 5, 6]) self.assertEqual(driver._hasparameters.get_expr_depends(), [('driver', 'comp')]) self.assertEqual(driver._hasparameters.get_referenced_compnames(), set(['comp'])) self.assertEqual(driver._hasparameters.get_referenced_varpaths(), set(['comp.x1d', 'comp.x2d'])) # Still have last set_parameters() values. var = driver.workflow._system.vec['u']['comp.x1d'] self.assertEqual(list(var), [7, 8, 9]) var = driver.workflow._system.vec['u']['comp.x2d'] self.assertEqual(list(var), [1, 2, 3, 4, 5, 6]) top.run() # Now have init_parameters() values. var = driver.workflow._system.vec['u']['comp.x1d'] self.assertEqual(list(var), [1, 1, 1]) var = driver.workflow._system.vec['u']['comp.x2d'] self.assertEqual(list(var), [2, 2, 2, 2, 2, 2]) def test_mixed_use(self): # Connect to one element of array and use another element as parameter. self.top.comp.x1d = [1., 2., 3.] self.top.add('exec_comp', ExecComp(exprs=['c=x+y', 'd=x-y'])) self.top.driver.workflow.add('exec_comp') self.top.connect('exec_comp.c', 'comp.x1d[0]') self.top.driver.add_parameter('comp.x1d[1]', low=-10, high=10, start=1.) self.top.run() def test_set_boundary_params(self): self.top = set_as_top(Assembly()) self.top.add('driver', MyDriver()) class ArrayComp2(Component): x = Array([0.0, 0.0], iotype='in') y = Array([0.0, 0.0], iotype='in') c = Array([0.0, 0.0], iotype='out') def execute(self): self.c = self.x + self.y self.top.add('comp', ArrayComp2()) self.top.driver.workflow.add('comp') self.top.create_passthrough('comp.x') self.top.create_passthrough('comp.c') self.top.connect('x', 'comp.y') self.top.driver.add_parameter(('x'), low=0., high=1e99) self.top.x = [22.0, 31.1] self.top.run() self.assertEqual(self.top.x[0], 22.) self.assertEqual(self.top.x[1], 31.1) self.assertEqual(self.top.comp.y[0], 22.) self.assertEqual(self.top.comp.y[1], 31.1)
class ArrayTest(unittest.TestCase): def setUp(self): self.top = Assembly() self.top.add('driver', MyDriver()) self.top.add('comp', ArrayComp()) self.top.driver.workflow.add('comp') def test_basic(self): top = self.top comp = top.comp driver = top.driver comp.x1d = [1, 2, 3] comp.x2d = [[1, 2, 3], [4, 5, 6]] top.run() self.assertEqual(comp.fx1d, 6.) self.assertEqual(list(comp.fx2d), [6., 15.]) code = "driver.add_parameter('comp.x1d')" assert_raises( self, code, globals(), locals(), ValueError, "driver: Trying to add parameter 'comp.x1d', but no" " lower limit was found and no 'low' argument was given." " One or the other must be specified.") code = "driver.add_parameter('comp.x1d', low=-10)" assert_raises( self, code, globals(), locals(), ValueError, "driver: Trying to add parameter 'comp.x1d', but no" " upper limit was found and no 'high' argument was given." " One or the other must be specified.") driver.add_parameter('comp.x1d', low=-10, high=10, start=1) code = "driver.add_parameter('comp.x2d')" assert_raises( self, code, globals(), locals(), ValueError, "driver: Trying to add parameter 'comp.x2d', but no" " lower limit was found and no 'low' argument was given." " One or the other must be specified.") code = "driver.add_parameter('comp.x2d', low=-10)" assert_raises( self, code, globals(), locals(), ValueError, "driver: Trying to add parameter 'comp.x2d', but no" " upper limit was found and no 'high' argument was given." " One or the other must be specified.") driver.add_parameter('comp.x2d', low=-10, high=10, start=2) top.run() comp.x1d = [1, 2, 3] comp.x2d = [[1, 2, 3], [4, 5, 6]] targets = driver.list_param_targets() self.assertEqual(targets, ['comp.x1d', 'comp.x2d']) targets = driver.list_param_group_targets() self.assertEqual(targets, [('comp.x1d', ), ('comp.x2d', )]) self.assertEqual(list(comp.x1d), [1, 2, 3]) self.assertEqual([list(row) for row in comp.x2d[:]], [[1, 2, 3], [4, 5, 6]]) driver.init_parameters() var = driver.workflow._system.vec['u']['comp.x1d'] self.assertEqual(list(var), [1, 1, 1]) var = driver.workflow._system.vec['u']['comp.x2d'] self.assertEqual(list(var), [2, 2, 2, 2, 2, 2]) driver.set_parameter_by_name('comp.x1d', 3) var = driver.workflow._system.vec['u']['comp.x1d'] self.assertEqual(list(var), [3, 3, 3]) driver.set_parameter_by_name('comp.x1d', array([4, 5, 6])) var = driver.workflow._system.vec['u']['comp.x1d'] self.assertEqual(list(var), [4, 5, 6]) driver.set_parameter_by_name('comp.x2d', 4) var = driver.workflow._system.vec['u']['comp.x2d'] self.assertEqual(list(var), [4, 4, 4, 4, 4, 4]) driver.set_parameter_by_name('comp.x2d', array([[5, 6, 7], [8, 9, 0]])) var = driver.workflow._system.vec['u']['comp.x2d'] self.assertEqual(list(var), [5, 6, 7, 8, 9, 0]) driver.set_parameters([7, 8, 9, 1, 2, 3, 4, 5, 6]) var = driver.workflow._system.vec['u']['comp.x1d'] self.assertEqual(list(var), [7, 8, 9]) var = driver.workflow._system.vec['u']['comp.x2d'] self.assertEqual(list(var), [1, 2, 3, 4, 5, 6]) self.assertEqual(driver._hasparameters.get_expr_depends(), [('driver', 'comp')]) self.assertEqual(driver._hasparameters.get_referenced_compnames(), set(['comp'])) self.assertEqual(driver._hasparameters.get_referenced_varpaths(), set(['comp.x1d', 'comp.x2d'])) # Still have last set_parameters() values. var = driver.workflow._system.vec['u']['comp.x1d'] self.assertEqual(list(var), [7, 8, 9]) var = driver.workflow._system.vec['u']['comp.x2d'] self.assertEqual(list(var), [1, 2, 3, 4, 5, 6]) top.run() # Now have init_parameters() values. var = driver.workflow._system.vec['u']['comp.x1d'] self.assertEqual(list(var), [1, 1, 1]) var = driver.workflow._system.vec['u']['comp.x2d'] self.assertEqual(list(var), [2, 2, 2, 2, 2, 2]) def test_mixed_use(self): # Connect to one element of array and use another element as parameter. self.top.comp.x1d = [1., 2., 3.] self.top.add('exec_comp', ExecComp(exprs=['c=x+y', 'd=x-y'])) self.top.driver.workflow.add('exec_comp') self.top.connect('exec_comp.c', 'comp.x1d[0]') self.top.driver.add_parameter('comp.x1d[1]', low=-10, high=10, start=1.) self.top.run() def test_set_boundary_params(self): self.top = set_as_top(Assembly()) self.top.add('driver', MyDriver()) class ArrayComp2(Component): x = Array([0.0, 0.0], iotype='in') y = Array([0.0, 0.0], iotype='in') c = Array([0.0, 0.0], iotype='out') def execute(self): self.c = self.x + self.y self.top.add('comp', ArrayComp2()) self.top.driver.workflow.add('comp') self.top.create_passthrough('comp.x') self.top.create_passthrough('comp.c') self.top.connect('x', 'comp.y') self.top.driver.add_parameter(('x'), low=0., high=1e99) self.top.x = [22.0, 31.1] self.top.run() self.assertEqual(self.top.x[0], 22.) self.assertEqual(self.top.x[1], 31.1) self.assertEqual(self.top.comp.y[0], 22.) self.assertEqual(self.top.comp.y[1], 31.1)
class TestLazyComponent(unittest.TestCase): def setUp(self): self.top = Assembly() self.top.add("t", TestComp()) self.top.add("s", SinkComp()) self.top.driver.workflow.add(["t", "s"]) self.top.set('t.a', 1) def tearDown(self): self.top = None def test_full_connected(self): self.top.connect('t.x', 's.i1') self.top.connect('t.y', 's.i2') self.top.connect('t.z', 's.i3') self.top.run() self.assertEqual(self.top.t.x, 2) self.assertEqual(self.top.t.y, 3) self.assertEqual(self.top.t.z, 4) self.assertEqual(self.top.get_valid(['t.x','t.y','t.z']), [True,True,True]) def test_partial_connected(self): self.top.connect('t.x', 's.i1') self.top.connect('t.y', 's.i2') self.top.run() self.assertEqual(self.top.t.x, 2) self.assertEqual(self.top.t.y, 3) self.assertEqual(self.top.t.z, 0) self.assertEqual(self.top.get_valid(['t.x','t.y','t.z']), [True,True,False]) #now try re-running with a different configuration to test the validy reseting self.top.disconnect('t') self.top.connect('t.x', 's.i1') self.top.set('t.a', 2) self.top.run() self.assertEqual(self.top.t.x, 3) self.assertEqual(self.top.t.y, 3) #this value is carried over from the first run call, but it's wrong... so not valid self.assertEqual(self.top.t.z, 0) self.assertEqual(self.top.get_valid(['t.x','t.y','t.z']), [True,False,False]) #not needed right now, since we're not checking for this #on regular component. """def test_partial_connect_exec_error(self): self.top.add('t', BrokenTestComp()) self.top.connect('t.x', 's.i1') self.top.set('t.a', 1) self.top.run() self.assertEqual(self.top.t.x, 10) self.assertEqual(self.top.t.y, 0) self.assertEqual(self.top.t.z, 0) self.top.connect('t.y', 's.i2') self.top.set('t.a', 2) try: self.top.run() except RuntimeError as err: msg = str(err) self.assertEqual(msg, "t: output 'y' is connected to something in your model, but was not calculated during execution") else: self.fail("RuntimeError Expected") """ def test_new_connection_invalidation(self): self.top.connect('t.x', 's.i1') self.top.set('t.a', 1) self.top.run() self.assertEqual(self.top.t.x, 2) self.assertEqual(self.top.t.y, 0) self.assertEqual(self.top.t.z, 0) self.assertEqual(self.top.get_valid(['t.x','t.y','t.z']), [True,False,False]) #new connection is made, but no inputs are invalid. Still need to run! self.top.connect('t.y', 's.i2') self.top.run() self.assertEqual(self.top.t.x, 2) self.assertEqual(self.top.t.y, 3) self.assertEqual(self.top.t.z, 0) self.assertEqual(self.top.get_valid(['t.x','t.y','t.z']), [True,True,False]) def test_dynamic_trait(self): self.top.connect('t.x', 's.i1') self.top.connect('t.y', 's.i2') self.top.t.add('w', Float(0.0, iotype="out")) self.top.connect('t.w', 's.i3') #not checking for this yet #try: # self.top.run() #except RuntimeError as err: # msg = str(err) # self.assertEqual(msg, "t (1-1): output 'w' is connected to something in your model, but was not calculated during execution") #else: # self.fail("RuntimeError Expected") self.top.run() self.assertEqual(self.top.get_valid(['t.w','t.x','t.y','t.z']), [True,True,True,False]) def test_output_stays_at_default(self): # check that validity is managed properly if outputs are calcualted, # but their values stay at the initial/default setting #note: this is not really necessary, unless we start testing #that outputs were actually calculated self.top.connect('t.x', 's.i1') self.top.set('t.a', -1) self.top.run() self.assertEqual(self.top.t.x, 0) self.assertEqual(self.top.t.y, 0) self.assertEqual(self.top.t.z, 0) self.assertEqual(self.top.t.get_valid(['x','y','z']), [True,False,False])
class ArrayTest(unittest.TestCase): def setUp(self): self.top = Assembly() self.top.add('driver', MyDriver()) self.top.add('comp', ArrayComp()) self.top.driver.workflow.add('comp') def test_basic(self): top = self.top comp = top.comp driver = top.driver comp.x1d = [1, 2, 3] comp.x2d = [[1, 2, 3], [4, 5, 6]] top.run() self.assertEqual(comp.fx1d, 6.) self.assertEqual(list(comp.fx2d), [6., 15.]) code = "driver.add_parameter('comp.x1d')" assert_raises( self, code, globals(), locals(), ValueError, "driver: Trying to add parameter 'comp.x1d', but no" " lower limit was found and no 'low' argument was given." " One or the other must be specified.") code = "driver.add_parameter('comp.x1d', low=-10)" assert_raises( self, code, globals(), locals(), ValueError, "driver: Trying to add parameter 'comp.x1d', but no" " upper limit was found and no 'high' argument was given." " One or the other must be specified.") driver.add_parameter('comp.x1d', low=-10, high=10, start=1) code = "driver.add_parameter('comp.x2d')" assert_raises( self, code, globals(), locals(), ValueError, "driver: Trying to add parameter 'comp.x2d', but no" " lower limit was found and no 'low' argument was given." " One or the other must be specified.") code = "driver.add_parameter('comp.x2d', low=-10)" assert_raises( self, code, globals(), locals(), ValueError, "driver: Trying to add parameter 'comp.x2d', but no" " upper limit was found and no 'high' argument was given." " One or the other must be specified.") driver.add_parameter('comp.x2d', low=-10, high=10, start=2) targets = driver.list_param_targets() self.assertEqual(targets, ['comp.x1d', 'comp.x2d']) targets = driver.list_param_group_targets() self.assertEqual(targets, [('comp.x1d', ), ('comp.x2d', )]) self.assertEqual(list(comp.x1d), [1, 2, 3]) self.assertEqual([list(row) for row in comp.x2d[:]], [[1, 2, 3], [4, 5, 6]]) driver.init_parameters() self.assertEqual(list(comp.x1d), [1, 1, 1]) self.assertEqual([list(row) for row in comp.x2d[:]], [[2, 2, 2], [2, 2, 2]]) driver.set_parameter_by_name('comp.x1d', 3) self.assertEqual(list(comp.x1d), [3, 3, 3]) driver.set_parameter_by_name('comp.x1d', array([4, 5, 6])) self.assertEqual(list(comp.x1d), [4, 5, 6]) driver.set_parameter_by_name('comp.x2d', 4) self.assertEqual([list(row) for row in comp.x2d[:]], [[4, 4, 4], [4, 4, 4]]) driver.set_parameter_by_name('comp.x2d', array([[5, 6, 7], [8, 9, 0]])) self.assertEqual([list(row) for row in comp.x2d[:]], [[5, 6, 7], [8, 9, 0]]) driver.set_parameters([7, 8, 9, 1, 2, 3, 4, 5, 6]) self.assertEqual(list(comp.x1d), [7, 8, 9]) self.assertEqual([list(row) for row in comp.x2d[:]], [[1, 2, 3], [4, 5, 6]]) self.assertEqual(driver._hasparameters.get_expr_depends(), [('driver', 'comp'), ('driver', 'comp')]) self.assertEqual(driver._hasparameters.get_referenced_compnames(), set(['comp'])) self.assertEqual(driver._hasparameters.get_referenced_varpaths(), set(['comp.x1d', 'comp.x2d'])) # Still have last set_parameters() values. self.assertEqual(list(comp.x1d), [7, 8, 9]) self.assertEqual([list(row) for row in comp.x2d[:]], [[1, 2, 3], [4, 5, 6]]) top.run() # Now have init_parameters() values. self.assertEqual(list(comp.x1d), [1, 1, 1]) self.assertEqual([list(row) for row in comp.x2d[:]], [[2, 2, 2], [2, 2, 2]]) self.assertEqual(comp.fx1d, 3) self.assertEqual(list(comp.fx2d), [6, 6]) def test_mixed_use(self): # Connect to one element of array and use another element as parameter. self.top.comp.x1d = [1, 2, 3] self.top.add('exec_comp', ExecComp(exprs=['c=x+y', 'd=x-y'])) self.top.driver.workflow.add('exec_comp') self.top.connect('exec_comp.c', 'comp.x1d[0]') self.top.driver.add_parameter('comp.x1d[1]', low=-10, high=10, start=1) self.top.run()
top.sim_EPA_city.workflow.add('vehicle') top.sim_EPA_city.velocity_str = 'vehicle.velocity' top.sim_EPA_city.throttle_str = 'vehicle.throttle' top.sim_EPA_city.gear_str = 'vehicle.current_gear' top.sim_EPA_city.acceleration_str = 'vehicle.acceleration' top.sim_EPA_city.fuel_burn_str = 'vehicle.fuel_burn' top.sim_EPA_city.overspeed_str = 'vehicle.overspeed' top.sim_EPA_city.underspeed_str = 'vehicle.underspeed' top.sim_EPA_city.profilename = 'EPA-city.csv' top.sim_EPA_highway.workflow.add('vehicle') top.sim_EPA_highway.velocity_str = 'vehicle.velocity' top.sim_EPA_highway.throttle_str = 'vehicle.throttle' top.sim_EPA_highway.gear_str = 'vehicle.current_gear' top.sim_EPA_highway.acceleration_str = 'vehicle.acceleration' top.sim_EPA_highway.fuel_burn_str = 'vehicle.fuel_burn' top.sim_EPA_highway.overspeed_str = 'vehicle.overspeed' top.sim_EPA_highway.underspeed_str = 'vehicle.underspeed' top.sim_EPA_highway.profilename = 'EPA-highway.csv' top.run() print "Time (0-60): ", top.sim_acc.accel_time print "City MPG: ", top.sim_EPA_city.fuel_economy print "Highway MPG: ", top.sim_EPA_highway.fuel_economy print "\nElapsed time: ", time.time() - ttime # End driving_sim.py
def test_nested_array_full_and_partial_passthrough(self): top = Assembly() top.add('nest', Assembly()) top.nest.add('comp1', ArrayComp2D()) top.nest.add('comp2', ArrayComp2D()) top.driver.gradient_options.lin_solver = 'petsc_ksp' top.nest.driver.gradient_options.lin_solver = 'petsc_ksp' top.nest.driver.workflow.add(['comp1', 'comp2']) top.nest.create_passthrough('comp1.x', 'x') top.nest.create_passthrough('comp1.y', 'y1') top.nest.create_passthrough('comp2.y', 'y2') top.nest.connect('x[-1, -1]', 'comp2.x[-1, -1]') top.add('driver', SimpleDriver()) top.driver.workflow.add(['nest']) top.run() Jbase = top.nest.comp1.provideJ() J = top.driver.calc_gradient(inputs=['nest.x'], outputs=['nest.y1', 'nest.y2'], mode='fd') diff = abs(J[0:4, :] - Jbase) assert_rel_error(self, diff.max(), 0.0, .00001) diff = abs(J[0:4, -1] - Jbase[:, -1]) assert_rel_error(self, diff.max(), 0.0, .00001) diff = abs(J[4:, :-1]) assert_rel_error(self, diff.max(), 0.0, .00001) J = top.driver.calc_gradient(inputs=['nest.x'], outputs=['nest.y1', 'nest.y2'], mode='forward') diff = abs(J[0:4, :] - Jbase) assert_rel_error(self, diff.max(), 0.0, .00001) diff = abs(J[0:4, -1] - Jbase[:, -1]) assert_rel_error(self, diff.max(), 0.0, .00001) diff = abs(J[4:, :-1]) assert_rel_error(self, diff.max(), 0.0, .00001) Jdict = top.driver.calc_gradient(inputs=['nest.x'], outputs=['nest.y1', 'nest.y2'], mode='forward', return_format='dict') diff = Jdict['nest.y1']['nest.x'] - Jbase assert_rel_error(self, diff.max(), 0.0, .00001) diff = Jdict['nest.y2']['nest.x'] - J[4:, :] assert_rel_error(self, diff.max(), 0.0, .00001) J = top.driver.calc_gradient(inputs=['nest.x'], outputs=['nest.y1', 'nest.y2'], mode='adjoint') diff = abs(J[0:4, :] - Jbase) assert_rel_error(self, diff.max(), 0.0, .00001) diff = abs(J[0:4, -1] - Jbase[:, -1]) assert_rel_error(self, diff.max(), 0.0, .00001) diff = abs(J[4:, :-1]) assert_rel_error(self, diff.max(), 0.0, .00001) Jdict = top.driver.calc_gradient(inputs=['nest.x'], outputs=['nest.y1', 'nest.y2'], mode='adjoint', return_format='dict') diff = Jdict['nest.y1']['nest.x'] - Jbase assert_rel_error(self, diff.max(), 0.0, .00001) diff = Jdict['nest.y2']['nest.x'] - J[4:, :] assert_rel_error(self, diff.max(), 0.0, .00001)
top.sim_EPA_city.workflow.add('vehicle') top.sim_EPA_city.velocity_str = 'vehicle.velocity' top.sim_EPA_city.throttle_str = 'vehicle.throttle' top.sim_EPA_city.gear_str = 'vehicle.current_gear' top.sim_EPA_city.acceleration_str = 'vehicle.acceleration' top.sim_EPA_city.fuel_burn_str = 'vehicle.fuel_burn' top.sim_EPA_city.overspeed_str = 'vehicle.overspeed' top.sim_EPA_city.underspeed_str = 'vehicle.underspeed' top.sim_EPA_city.profilename = 'EPA-city.csv' top.sim_EPA_highway.workflow.add('vehicle') top.sim_EPA_highway.velocity_str = 'vehicle.velocity' top.sim_EPA_highway.throttle_str = 'vehicle.throttle' top.sim_EPA_highway.gear_str = 'vehicle.current_gear' top.sim_EPA_highway.acceleration_str = 'vehicle.acceleration' top.sim_EPA_highway.fuel_burn_str = 'vehicle.fuel_burn' top.sim_EPA_highway.overspeed_str = 'vehicle.overspeed' top.sim_EPA_highway.underspeed_str = 'vehicle.underspeed' top.sim_EPA_highway.profilename = 'EPA-highway.csv' top.run() print "Time (0-60): ", top.sim_acc.accel_time print "City MPG: ", top.sim_EPA_city.fuel_economy print "Highway MPG: ", top.sim_EPA_highway.fuel_economy print "\nElapsed time: ", time.time()-ttime # End driving_sim.py
class ArrayTest(unittest.TestCase): def setUp(self): self.top = Assembly() self.top.add('driver', MyDriver()) self.top.add('comp', ArrayComp()) self.top.driver.workflow.add('comp') def test_basic(self): top = self.top comp = top.comp driver = top.driver comp.x1d = [1, 2, 3] comp.x2d = [[1, 2, 3], [4, 5, 6]] top.run() self.assertEqual(comp.fx1d, 6.) self.assertEqual(list(comp.fx2d), [6., 15.]) code = "driver.add_parameter('comp.x1d')" assert_raises(self, code, globals(), locals(), ValueError, "driver: Trying to add parameter 'comp.x1d', but no" " lower limit was found and no 'low' argument was given." " One or the other must be specified.") code = "driver.add_parameter('comp.x1d', low=-10)" assert_raises(self, code, globals(), locals(), ValueError, "driver: Trying to add parameter 'comp.x1d', but no" " upper limit was found and no 'high' argument was given." " One or the other must be specified.") driver.add_parameter('comp.x1d', low=-10, high=10, start=1) code = "driver.add_parameter('comp.x2d')" assert_raises(self, code, globals(), locals(), ValueError, "driver: Trying to add parameter 'comp.x2d', but no" " lower limit was found and no 'low' argument was given." " One or the other must be specified.") code = "driver.add_parameter('comp.x2d', low=-10)" assert_raises(self, code, globals(), locals(), ValueError, "driver: Trying to add parameter 'comp.x2d', but no" " upper limit was found and no 'high' argument was given." " One or the other must be specified.") driver.add_parameter('comp.x2d', low=-10, high=10, start=2) targets = driver.list_param_targets() self.assertEqual(targets, ['comp.x1d', 'comp.x2d']) targets = driver.list_param_group_targets() self.assertEqual(targets, [('comp.x1d',), ('comp.x2d',)]) self.assertEqual(list(comp.x1d), [1, 2, 3]) self.assertEqual([list(row) for row in comp.x2d[:]], [[1, 2, 3], [4, 5, 6]]) driver.init_parameters() self.assertEqual(list(comp.x1d), [1, 1, 1]) self.assertEqual([list(row) for row in comp.x2d[:]], [[2, 2, 2], [2, 2, 2]]) driver.set_parameter_by_name('comp.x1d', 3) self.assertEqual(list(comp.x1d), [3, 3, 3]) driver.set_parameter_by_name('comp.x1d', array([4, 5, 6])) self.assertEqual(list(comp.x1d), [4, 5, 6]) driver.set_parameter_by_name('comp.x2d', 4) self.assertEqual([list(row) for row in comp.x2d[:]], [[4, 4, 4], [4, 4, 4]]) driver.set_parameter_by_name('comp.x2d', array([[5, 6, 7], [8, 9, 0]])) self.assertEqual([list(row) for row in comp.x2d[:]], [[5, 6, 7], [8, 9, 0]]) driver.set_parameters([7, 8, 9, 1, 2, 3, 4, 5, 6]) self.assertEqual(list(comp.x1d), [7, 8, 9]) self.assertEqual([list(row) for row in comp.x2d[:]], [[1, 2, 3], [4, 5, 6]]) self.assertEqual(driver._hasparameters.get_expr_depends(), [('driver', 'comp'), ('driver', 'comp')]) self.assertEqual(driver._hasparameters.get_referenced_compnames(), set(['comp'])) self.assertEqual(driver._hasparameters.get_referenced_varpaths(), set(['comp.x1d', 'comp.x2d'])) # Still have last set_parameters() values. self.assertEqual(list(comp.x1d), [7, 8, 9]) self.assertEqual([list(row) for row in comp.x2d[:]], [[1, 2, 3], [4, 5, 6]]) top.run() # Now have init_parameters() values. self.assertEqual(list(comp.x1d), [1, 1, 1]) self.assertEqual([list(row) for row in comp.x2d[:]], [[2, 2, 2], [2, 2, 2]]) self.assertEqual(comp.fx1d, 3) self.assertEqual(list(comp.fx2d), [6, 6]) def test_mixed_use(self): # Connect to one element of array and use another element as parameter. self.top.comp.x1d = [1, 2, 3] self.top.add('exec_comp', ExecComp(exprs=['c=x+y', 'd=x-y'])) self.top.driver.workflow.add('exec_comp') self.top.connect('exec_comp.c', 'comp.x1d[0]') self.top.driver.add_parameter('comp.x1d[1]', low=-10, high=10, start=1) self.top.run()
def test_nested_2Darray(self): top = Assembly() top.add('nest', Assembly()) top.nest.add('comp', ArrayComp2D()) top.driver.workflow.add(['nest']) top.nest.driver.workflow.add(['comp']) top.nest.create_passthrough('comp.x') top.nest.create_passthrough('comp.y') top.run() J = top.driver.workflow.calc_gradient(inputs=[ 'nest.x', ], outputs=['nest.y'], mode='forward') diff = J - top.nest.comp.J assert_rel_error(self, diff.max(), 0.0, .000001) top.driver.workflow.config_changed() top.nest.driver.workflow.config_changed() J = top.driver.workflow.calc_gradient(inputs=[ 'nest.x[0, 0]', ], outputs=['nest.y[0, 0]'], mode='forward') diff = J - top.nest.comp.J[0, 0] assert_rel_error(self, diff.max(), 0.0, .000001) top.driver.workflow.config_changed() top.nest.driver.workflow.config_changed() J = top.driver.workflow.calc_gradient(inputs=[ 'nest.x[0, 1]', ], outputs=['nest.y[1, 0]'], mode='forward') diff = J - top.nest.comp.J[1, 2] assert_rel_error(self, diff.max(), 0.0, .000001) top.driver.workflow.config_changed() top.nest.driver.workflow.config_changed() J = top.driver.workflow.calc_gradient(inputs=[ 'nest.x[0, 1]', ], outputs=['nest.y[1, 0]'], mode='fd') diff = J - top.nest.comp.J[1, 2] assert_rel_error(self, diff.max(), 0.0, .000001) top.driver.workflow.config_changed() top.nest.driver.workflow.config_changed() J = top.driver.workflow.calc_gradient(inputs=[ 'nest.x[0, -1]', ], outputs=['nest.y[-1, 0]'], mode='forward') diff = J - top.nest.comp.J[1, 2] assert_rel_error(self, diff.max(), 0.0, .000001) top.driver.workflow.config_changed() top.nest.driver.workflow.config_changed() J = top.driver.workflow.calc_gradient(inputs=[ 'nest.x[0, -1]', ], outputs=['nest.y[-1, 0]'], mode='fd') diff = J - top.nest.comp.J[1, 2] assert_rel_error(self, diff.max(), 0.0, .000001) top.driver.workflow.config_changed() top.nest.driver.workflow.config_changed() Jsub = top.nest.comp.J[2:3, 2:3] J = top.driver.workflow.calc_gradient(inputs=[ 'nest.x[1][:]', ], outputs=['nest.y[1][:]'], mode='forward') diff = J - Jsub top.run() top.driver.workflow.config_changed() top.nest.driver.workflow.config_changed() J = top.driver.workflow.calc_gradient(inputs=[ 'nest.x[1][:]', ], outputs=['nest.y[1][:]'], mode='fd') diff = J - Jsub
class TestCase_Residuals(unittest.TestCase): def setUp(self): """ Called before each test. """ self.model = Assembly() self.model.add('c1', MyComp()) self.model.add('c2', MyComp()) self.model.add('driver', SimpleDriver()) self.model.driver.workflow = CyclicWorkflow() self.model.driver.workflow.add(['c1', 'c2']) def tearDown(self): """ Called after each test. """ self.model = None def test_column_vector(self): self.model.c1.add('y_a', Array(iotype='out')) self.model.c1.y_a = array([[1.0], [2.0]]) self.model.c2.add('x_a', Array(iotype='in')) self.model.c2.x_a = array([[3.0], [6.0]]) self.model.connect('c1.y_a', 'c2.x_a') self.model.connect('c2.y', 'c1.x') self.model.driver.workflow.initialize_residual() self.model.run() dv = array([3.0, 5.0]) self.model.driver.workflow.set_independents(dv) indep = self.model.driver.workflow.get_independents() self.assertEqual(indep[0], 3.0) self.assertEqual(indep[1], 5.0) dep = self.model.driver.workflow.get_dependents() self.assertEqual(dep[0], -2.0) self.assertEqual(dep[1], -3.0) def test_row_vector(self): self.model.c1.add('y_a', Array(iotype='out')) self.model.c1.y_a = array([[1.0, 2.0]]) self.model.c2.add('x_a', Array(iotype='in')) self.model.c2.x_a = array([[3.0, 6.0]]) self.model.connect('c1.y_a', 'c2.x_a') self.model.connect('c2.y', 'c1.x') self.model.driver.workflow.initialize_residual() self.model.run() dv = array([3.0, 5.0]) self.model.driver.workflow.set_independents(dv) indep = self.model.driver.workflow.get_independents() self.assertEqual(indep[0], 3.0) self.assertEqual(indep[1], 5.0) dep = self.model.driver.workflow.get_dependents() self.assertEqual(dep[0], -2.0) self.assertEqual(dep[1], -3.0) def test_array_1D(self): self.model.c1.add('y_a', Array(iotype='out')) self.model.c1.y_a = array([1.0, 2.0]) self.model.c2.add('x_a', Array(iotype='in')) self.model.c2.x_a = array([3.0, 6.0]) self.model.connect('c1.y_a', 'c2.x_a') self.model.connect('c2.y', 'c1.x') self.model.driver.workflow.initialize_residual() self.model.run() dv = array([3.0, 5.0]) self.model.driver.workflow.set_independents(dv) indep = self.model.driver.workflow.get_independents() self.assertEqual(indep[0], 3.0) self.assertEqual(indep[1], 5.0) dep = self.model.driver.workflow.get_dependents() self.assertEqual(dep[0], -2.0) self.assertEqual(dep[1], -3.0) def test_full_matrix(self): self.model.c1.add('y_a', Array(iotype='out')) self.model.c1.y_a = array([[1.0, 2.0], [3.0, 4.0]]) self.model.c2.add('x_a', Array(iotype='in')) self.model.c2.x_a = array([[2.0, 5.0], [11.0, 17.0]]) self.model.connect('c1.y_a', 'c2.x_a') self.model.connect('c2.y', 'c1.x') self.model.driver.workflow.initialize_residual() self.model.run() dv = array([3.0, 5.0, -8.0, -13.0]) self.model.driver.workflow.set_independents(dv) indep = self.model.driver.workflow.get_independents() self.assertEqual(indep[0], 3.0) self.assertEqual(indep[1], 5.0) self.assertEqual(indep[2], -8.0) self.assertEqual(indep[3], -13.0) dep = self.model.driver.workflow.get_dependents() self.assertEqual(dep[0], -2.0) self.assertEqual(dep[1], -3.0) self.assertEqual(dep[2], 11.0) self.assertEqual(dep[3], 17.0) def test_matrix_element(self): # Array element to scalar. self.model.c1.add('y_a', Array(iotype='out')) self.model.c1.y_a = array([[1.0, 2.0], [3.0, 4.0]]) self.model.c2.x = 7.0 self.model.connect('c1.y_a[0, 0]', 'c2.x') self.model.connect('c2.y', 'c1.x') self.model.driver.workflow.initialize_residual() self.model.run() dv = array([35.0]) self.model.driver.workflow.set_independents(dv) indep = self.model.driver.workflow.get_independents() self.assertEqual(indep[0], 35.0) dep = self.model.driver.workflow.get_dependents() self.assertEqual(dep[0], -34.0) def test_vtree(self): self.model.c1.add('vt_out', VarTree(Tree1(), iotype='out')) self.model.c2.add('vt_in', VarTree(Tree1(), iotype='in')) self.model.c2.vt_in.a1 = 4. self.model.c2.vt_in.b1 = array([7.0, 12.0]) self.model.c2.vt_in.vt1.c1 = 13. self.model.c2.vt_in.vt1.d1 = array([-1.0, 2.0]) self.model.connect('c1.vt_out', 'c2.vt_in') self.model.connect('c2.y', 'c1.x') self.model.driver.workflow.initialize_residual() indep = self.model.driver.workflow.get_independents() self.assertEqual(indep[0], 4.0) self.assertEqual(indep[1], 7.0) self.assertEqual(indep[2], 12.0) self.assertEqual(indep[3], 13.0) self.assertEqual(indep[4], -1.0) self.assertEqual(indep[5], 2.0) dep = self.model.driver.workflow.get_dependents() self.assertEqual(dep[0], -1.0) self.assertEqual(dep[1], -4.0) self.assertEqual(dep[2], -5.0) self.assertEqual(dep[3], -4.0) self.assertEqual(dep[4], 6.0) self.assertEqual(dep[5], 9.0) dv = array([81.0, 82.0, 83.0, 84.0, 85.0, 86.0]) self.model.driver.workflow.set_independents(dv) indep = self.model.driver.workflow.get_independents() self.assertEqual(indep[0], 81.0) self.assertEqual(indep[1], 82.0) self.assertEqual(indep[2], 83.0) self.assertEqual(indep[3], 84.0) self.assertEqual(indep[4], 85.0) self.assertEqual(indep[5], 86.0) def test_vtree_leaf(self): self.model.c1.add('vt_out', VarTree(Tree1(), iotype='out')) self.model.c2.add('vt_in', VarTree(Tree1(), iotype='in')) self.model.c2.vt_in.b1 = array([7.0, 12.0]) self.model.connect('c1.vt_out.b1', 'c2.vt_in.b1') self.model.connect('c2.y', 'c1.x') self.model.driver.workflow.initialize_residual() indep = self.model.driver.workflow.get_independents() self.assertEqual(indep[0], 7.0) self.assertEqual(indep[1], 12.0) dep = self.model.driver.workflow.get_dependents() self.assertEqual(dep[0], -4.0) self.assertEqual(dep[1], -5.0) dv = array([13.0, 15.0]) self.model.driver.workflow.set_independents(dv) indep = self.model.driver.workflow.get_independents() self.assertEqual(indep[0], 13.0) self.assertEqual(indep[1], 15.0)
self.assertEqual(str(err), msg) else: self.fail('Exception expected') # Unconnected added twice shouldn't cause exception. asm = Assembly() asm.add('a', Simple()) asm.add('b', Simple()) dup1 = asm.add('dup1', Simple()) dup2 = asm.add('dup2', Simple()) self.assertEqual(dup1.exec_count, 0) self.assertEqual(dup2.exec_count, 0) sequence = ['dup1', 'a', 'dup2', 'dup1', 'b', 'dup1', 'dup2'] asm.driver.workflow.add(sequence) self.assertEqual([comp.name for comp in asm.driver.workflow], sequence) asm.run() self.assertEqual(dup1.exec_count, 1) self.assertEqual(dup2.exec_count, 1) # With force_execute True, all executions are run. asm = Assembly() asm.add('a', Simple()) asm.add('b', Simple()) dup1 = asm.add('dup1', Simple()) dup1.force_execute = True dup2 = asm.add('dup2', Simple()) dup2.force_execute = True self.assertEqual(dup1.exec_count, 0) self.assertEqual(dup2.exec_count, 0) sequence = ['dup1', 'a', 'dup2', 'dup1', 'b', 'dup1', 'dup2'] asm.driver.workflow.add(sequence)
self.assertEqual(str(err), msg) else: self.fail('Exception expected') # Unconnected added twice shouldn't cause exception. asm = Assembly() asm.add('a', Simple()) asm.add('b', Simple()) dup1 = asm.add('dup1', Simple()) dup2 = asm.add('dup2', Simple()) self.assertEqual(dup1.exec_count, 0) self.assertEqual(dup2.exec_count, 0) sequence = ['dup1', 'a', 'dup2', 'dup1', 'b', 'dup1', 'dup2'] asm.driver.workflow.add(sequence) self.assertEqual([comp.name for comp in asm.driver.workflow], sequence) asm.run() self.assertEqual(dup1.exec_count, 3) self.assertEqual(dup2.exec_count, 2) asm = Assembly() asm.add('a', Simple()) asm.add('b', Simple()) dup1 = asm.add('dup1', Simple()) dup2 = asm.add('dup2', Simple()) self.assertEqual(dup1.exec_count, 0) self.assertEqual(dup2.exec_count, 0) sequence = ['dup1', 'a', 'dup2', 'dup1', 'b', 'dup1', 'dup2'] asm.driver.workflow.add(sequence) self.assertEqual([comp.name for comp in asm.driver.workflow], sequence) asm.run() self.assertEqual(dup1.exec_count, 3)