def test_one_to_two_fd(self): top = set_as_top(Assembly()) exp1 = ["y1 = 3.0*x", "y2 = 4.0*x"] exp2 = ["y = -2.0*x"] exp3 = ["y = 5.0*x"] deriv1 = ["dy1_dx = 3.0", "dy2_dx = 4.0"] deriv2 = ["dy_dx = -2.0"] deriv3 = ["dy_dx = 5.0"] top.add('comp1', ExecCompWithDerivatives(exp1, deriv1)) top.add('comp2', ExecCompWithDerivatives(exp2, deriv2)) top.add('comp3', ExecCompWithDerivatives(exp3, deriv3)) top.add('driver', SimpleDriver()) top.driver.workflow.add(['comp1', 'comp2', 'comp3']) top.connect('comp1.y1', 'comp2.x') top.connect('comp1.y2', 'comp3.x') top.driver.add_parameter('comp1.x', low=-100, high=100) top.driver.add_constraint('comp2.y < 1000') top.driver.add_constraint('comp3.y < 1000') top.run() J = top.driver.workflow.calc_gradient(mode='fd', return_format='dict') J = top.driver.workflow._system.get_combined_J(J) collective_assert_rel_error(self, J['_pseudo_0.out0']['comp1.x'][0][0], -6.0, 0.0001) collective_assert_rel_error(self, J['_pseudo_1.out0']['comp1.x'][0][0], 20.0, 0.0001)
def test_parameter_groups(self): self.top = set_as_top(Assembly()) exp1 = ['y = 2.0*x'] deriv1 = ['dy_dx = 2.0'] self.top.add('driver', Driv()) self.top.add('comp1', ExecCompWithDerivatives(exp1, deriv1)) self.top.add('comp2', ExecCompWithDerivatives(exp1, deriv1)) self.top.driver.workflow.add(['comp1', 'comp2']) # Top driver setup self.top.driver.differentiator = Analytic() obj = 'comp1.y+comp2.y' self.top.driver.add_parameter(['comp1.x', 'comp2.x'], low=-100., high=100., fd_step=.001) self.top.driver.add_objective(obj) self.top.comp1.x1 = 1.0 self.top.comp2.x2 = 1.0 self.top.run() self.top.driver.differentiator.calc_gradient() grad = self.top.driver.differentiator.get_gradient(obj) assert_rel_error(self, grad[0], 4.0, .001)
def test_diverge_converge_LinGS_adjoint(self): self.top = set_as_top(Assembly()) exp1 = ['y1 = 2.0*x1**2', 'y2 = 3.0*x1'] deriv1 = ['dy1_dx1 = 4.0*x1', 'dy2_dx1 = 3.0'] exp2 = ['y1 = 0.5*x1'] deriv2 = ['dy1_dx1 = 0.5'] exp3 = ['y1 = 3.5*x1'] deriv3 = ['dy1_dx1 = 3.5'] exp4 = ['y1 = x1 + 2.0*x2', 'y2 = 3.0*x1', 'y3 = x1*x2'] deriv4 = ['dy1_dx1 = 1.0', 'dy1_dx2 = 2.0', 'dy2_dx1 = 3.0', 'dy2_dx2 = 0.0', 'dy3_dx1 = x2', 'dy3_dx2 = x1'] exp5 = ['y1 = x1 + 3.0*x2 + 2.0*x3'] deriv5 = ['dy1_dx1 = 1.0', 'dy1_dx2 = 3.0', 'dy1_dx3 = 2.0'] self.top.add('comp1', ExecCompWithDerivatives(exp1, deriv1)) self.top.add('comp2', ExecCompWithDerivatives(exp2, deriv2)) self.top.add('comp3', ExecCompWithDerivatives(exp3, deriv3)) self.top.add('comp4', ExecCompWithDerivatives(exp4, deriv4)) self.top.add('comp5', ExecCompWithDerivatives(exp5, deriv5)) self.top.driver.workflow.add(['comp1', 'comp2', 'comp3', 'comp4', 'comp5']) self.top.connect('comp1.y1', 'comp2.x1') self.top.connect('comp1.y2', 'comp3.x1') self.top.connect('comp2.y1', 'comp4.x1') self.top.connect('comp3.y1', 'comp4.x2') self.top.connect('comp4.y1', 'comp5.x1') self.top.connect('comp4.y2', 'comp5.x2') self.top.connect('comp4.y3', 'comp5.x3') self.top.comp1.x1 = 2.0 self.top.driver.gradient_options.lin_solver = 'linear_gs' self.top.driver.gradient_options.maxiter = 1 self.top.run() J = self.top.driver.calc_gradient(inputs=['comp1.x1'], outputs=['comp5.y1'], mode='adjoint', return_format='dict') collective_assert_rel_error(self, J['comp5.y1']['comp1.x1'][0][0], 313.0, 0.0001)
def test_diverge_converge_adjoint(self): self.top = set_as_top(Assembly()) exp1 = ['y1 = 2.0*x1**2', 'y2 = 3.0*x1'] deriv1 = ['dy1_dx1 = 4.0*x1', 'dy2_dx1 = 3.0'] exp2 = ['y1 = 0.5*x1'] deriv2 = ['dy1_dx1 = 0.5'] exp3 = ['y1 = 3.5*x1'] deriv3 = ['dy1_dx1 = 3.5'] exp4 = ['y1 = x1 + 2.0*x2', 'y2 = 3.0*x1', 'y3 = x1*x2'] deriv4 = ['dy1_dx1 = 1.0', 'dy1_dx2 = 2.0', 'dy2_dx1 = 3.0', 'dy2_dx2 = 0.0', 'dy3_dx1 = x2', 'dy3_dx2 = x1'] exp5 = ['y1 = x1 + 3.0*x2 + 2.0*x3'] deriv5 = ['dy1_dx1 = 1.0', 'dy1_dx2 = 3.0', 'dy1_dx3 = 2.0'] self.top.add('comp1', ExecCompWithDerivatives(exp1, deriv1)) self.top.add('comp2', ExecCompWithDerivatives(exp2, deriv2)) self.top.add('comp3', ExecCompWithDerivatives(exp3, deriv3)) self.top.add('comp4', ExecCompWithDerivatives(exp4, deriv4)) self.top.add('comp5', ExecCompWithDerivatives(exp5, deriv5)) self.top.driver.workflow.add(['comp1', 'comp2', 'comp3', 'comp4', 'comp5']) self.top.connect('comp1.y1', 'comp2.x1') self.top.connect('comp1.y2', 'comp3.x1') self.top.connect('comp2.y1', 'comp4.x1') self.top.connect('comp3.y1', 'comp4.x2') self.top.connect('comp4.y1', 'comp5.x1') self.top.connect('comp4.y2', 'comp5.x2') self.top.connect('comp4.y3', 'comp5.x3') self.top.comp1.x1 = 2.0 self.top.run() J = self.top.driver.calc_gradient(inputs=['comp1.x1'], outputs=['comp5.y1'], mode='adjoint', return_format='dict') #from openmdao.util.dotgraph import plot_system_tree #plot_system_tree(self.top._system) #print J collective_assert_rel_error(self, J['comp5.y1']['comp1.x1'][0][0], 313.0, 0.0001)
def test_smarter_nondifferentiable_blocks(self): top = set_as_top(Assembly()) top.add( 'comp1', ExecCompWithDerivatives(['y=2.0*x + 3.0*x2'], ['dy_dx = 2.0', 'dy_dx2 = 3.0'])) top.add('comp2', ExecComp(['y=2.0*x + 3.0*x2', 'y2=4.0*x + 5.0*x2'])) top.add( 'comp3', ExecCompWithDerivatives(['y=2.0*x + 3.0*x2'], ['dy_dx = 2.0', 'dy_dx2 = 3.0'])) top.add('comp4', ExecComp(['y=2.0*x + 3.0*x2'])) top.add( 'comp5', ExecCompWithDerivatives(['y=2.0*x + 3.0*x2'], ['dy_dx = 2.0', 'dy_dx2 = 3.0'])) top.driver.workflow.add(['comp1', 'comp2', 'comp3', 'comp4', 'comp5']) top.connect('comp1.y', 'comp2.x') top.connect('comp2.y', 'comp3.x') top.connect('comp2.y2', 'comp4.x') top.connect('comp3.y', 'comp4.x2') top.connect('comp4.y', 'comp5.x') top.run() J = top.driver.workflow.calc_gradient(inputs=['comp1.x'], outputs=['comp5.y'], mode='forward') pa1 = top.driver.workflow._derivative_graph.node['~0']['pa_object'] self.assertTrue('comp1' not in pa1.comps) self.assertTrue('comp2' in pa1.comps) self.assertTrue('comp3' in pa1.comps) self.assertTrue('comp4' in pa1.comps) self.assertTrue('comp5' not in pa1.comps) self.assertTrue(pa1.comps == pa1.itercomps) top.replace( 'comp4', ExecCompWithDerivatives(['y=2.0*x + 3.0*x2'], ['dy_dx = 2.0', 'dy_dx2 = 3.0'])) top.run() top.driver.workflow.config_changed() J = top.driver.workflow.calc_gradient(inputs=['comp1.x'], outputs=['comp5.y'], mode='forward') pa1 = top.driver.workflow._derivative_graph.node['~0']['pa_object'] self.assertTrue('comp1' not in pa1.comps) self.assertTrue('comp2' in pa1.comps) self.assertTrue('comp3' not in pa1.comps) self.assertTrue('comp4' not in pa1.comps) self.assertTrue('comp5' not in pa1.comps) self.assertTrue(pa1.comps == pa1.itercomps)
def test_smarter_nondifferentiable_blocks(self): top = set_as_top(Assembly()) top.add( 'comp1', ExecCompWithDerivatives(['y=2.0*x + 3.0*x2'], ['dy_dx = 2.0', 'dy_dx2 = 3.0'])) top.add('comp2', ExecComp(['y=2.0*x + 3.0*x2', 'y2=4.0*x + 5.0*x2'])) top.add( 'comp3', ExecCompWithDerivatives(['y=2.0*x + 3.0*x2'], ['dy_dx = 2.0', 'dy_dx2 = 3.0'])) top.add('comp4', ExecComp(['y=2.0*x + 3.0*x2'])) top.add( 'comp5', ExecCompWithDerivatives(['y=2.0*x + 3.0*x2'], ['dy_dx = 2.0', 'dy_dx2 = 3.0'])) top.driver.workflow.add(['comp1', 'comp2', 'comp3', 'comp4', 'comp5']) top.connect('comp1.y', 'comp2.x') top.connect('comp2.y', 'comp3.x') top.connect('comp2.y2', 'comp4.x') top.connect('comp3.y', 'comp4.x2') top.connect('comp4.y', 'comp5.x') top.run() J = top.driver.calc_gradient(inputs=['comp1.x'], outputs=['comp5.y'], mode='forward') self.assertTrue(len(top.driver.workflow._system.subsystems()) == 4) comp_list = simple_node_iter( top.driver.workflow._system.subsystems()[2]._nodes) self.assertTrue(len(comp_list) == 3) self.assertTrue('comp2' in comp_list) self.assertTrue('comp3' in comp_list) self.assertTrue('comp4' in comp_list) top.replace( 'comp4', ExecCompWithDerivatives(['y=2.0*x + 3.0*x2'], ['dy_dx = 2.0', 'dy_dx2 = 3.0'])) top.run() J = top.driver.calc_gradient(inputs=['comp1.x'], outputs=['comp5.y'], mode='forward') self.assertTrue(len(top.driver.workflow._system.subsystems()) == 6) comp_list = simple_node_iter( top.driver.workflow._system.subsystems()[2]._nodes) self.assertTrue(len(comp_list) == 1) self.assertTrue('comp2' in comp_list)
def test_medium_coupled(self): self.top = set_as_top(Assembly()) exp0 = ['y=x'] deriv0 = ['dy_dx = 1.0'] exp1 = ['y2 = 0.5*sin(x1) - 0.5*x1*y1'] deriv1 = ['dy2_dx1 = 0.5*cos(x1) - 0.5*y1', 'dy2_dy1 = -0.5*x1'] exp2 = ['y1 = x2*x2*y2'] deriv2 = ['dy1_dx2 = 2.0*y2*x2', 'dy1_dy2 = x2*x2'] exp4 = ['y=3.0*x'] deriv4 = ['dy_dx = 3.0'] self.top.add('driver', Driv()) self.top.add('comp0', ExecCompWithDerivatives(exp0, deriv0)) self.top.add('comp1', ExecCompWithDerivatives(exp1, deriv1)) self.top.add('comp2', ExecCompWithDerivatives(exp2, deriv2)) self.top.add('comp3', ExecCompWithDerivatives(exp4, deriv4)) #self.top.add('comp1', ExecComp(exp1)) #self.top.add('comp2', ExecComp(exp2)) self.top.add('solver', BroydenSolver()) self.top.driver.workflow.add(['solver']) self.top.solver.workflow.add(['comp0', 'comp1', 'comp2', 'comp3']) self.top.connect('comp0.y', 'comp1.x1') self.top.connect('comp1.y2', 'comp2.y2') self.top.connect('comp2.y1', 'comp3.x') # Solver setup self.top.solver.add_parameter('comp1.y1', low=-1.e99, high=1.e99) self.top.solver.add_constraint('comp2.y1 = comp1.y1') # Top driver setup #self.top.driver.differentiator = FiniteDifference() self.top.driver.differentiator = Analytic() obj = 'comp3.y' self.top.driver.add_parameter('comp0.x', low=-100., high=100., fd_step=.001) self.top.driver.add_objective(obj) self.top.comp0.x = 1.0 self.top.comp2.x2 = 1.0 self.top.run() self.top.driver.differentiator.calc_gradient() grad = self.top.driver.differentiator.get_gradient(obj) assert_rel_error(self, grad[0], 3.0 * 0.08660, .001)
def test_baseline_case(self): top = set_as_top(Assembly()) top.add('comp1', ExecCompWithDerivatives(['y1=2.0*x', 'y2=3.0*x', 'y3=4.0*x', 'y4=5.0*x'], ['dy1_dx = 2.0', 'dy2_dx = 3.0', 'dy3_dx = 4.0', 'dy4_dx = 5.0'])) top.add('comp2', ExecComp(['y = 2.0*x1 + x2 + x3 + x4'])) top.driver.workflow.add(['comp1', 'comp2']) top.connect('comp1.y1', 'comp2.x1') top.connect('comp1.y2', 'comp2.x2') top.connect('comp1.y3', 'comp2.x3') top.connect('comp1.y4', 'comp2.x4') top.run() self.assertEqual(top.comp2.exec_count, 1) top.driver.gradient_options.directional_fd = True J = top.driver.calc_gradient(inputs=['comp1.x'], outputs=['comp2.y']) # Ran 1 times, not 4. self.assertEqual(top.comp2.exec_count, 2) assert_rel_error(self, J[0, 0], 16.0, 0.0001) top.driver.gradient_options.directional_fd = False J = top.driver.calc_gradient(inputs=['comp1.x'], outputs=['comp2.y']) # Ran 4 times (4 fd steps). self.assertEqual(top.comp2.exec_count, 6) assert_rel_error(self, J[0, 0], 16.0, 0.0001) # Next, test param / obj top.add('driver', SimpleDriver()) top.driver.add_parameter('comp1.x', low=-1000, high=1000) top.driver.add_objective('comp2.y') top.run() self.assertEqual(top.comp2.exec_count, 7) top.driver.gradient_options.directional_fd = True J = top.driver.calc_gradient() # Ran 1 more times. self.assertEqual(top.comp2.exec_count, 8) assert_rel_error(self, J[0, 0], 16.0, 0.0001) J = top.driver.calc_gradient(mode='fd') # Ran 1 more times (full model fd, 2 edges). self.assertEqual(top.comp2.exec_count, 9) assert_rel_error(self, J[0, 0], 16.0, 0.0001)
def test_derivative_state_connection_internal_solve_apply_deriv(self): model = set_as_top(Assembly()) model.add('driver', SimpleDriver()) model.add('comp', MyComp_Deriv()) model.comp.add('c', Float(2.0, iotype="in")) model.comp.eval_only = False model.add('comp2', ExecCompWithDerivatives(["y=2*x"], ["dy_dx=2"])) model.driver.workflow.add(['comp', 'comp2']) model.connect('comp.z', 'comp2.x') model.run() #print model.comp.x, model.comp.y, model.comp.z, model.comp.res J = model.driver.calc_gradient(inputs=['comp.c'], outputs=['comp2.y']) assert_rel_error(self, J[0][0], -0.1666, 2e-3) J = model.driver.calc_gradient(inputs=['comp.c'], outputs=['comp2.y'], mode='adjoint') assert_rel_error(self, J[0][0], -0.1666, 2e-3) J = model.driver.calc_gradient(inputs=['comp.c'], outputs=['comp2.y'], mode='fd') assert_rel_error(self, J[0][0], -0.1666, 2e-3)
def test_simple_coupled_adjoint(self): self.top = set_as_top(Assembly()) exp1 = ['y2 = 0.5*sin(x1) - 0.5*x1*y1'] deriv1 = ['dy2_dx1 = 0.5*cos(x1) - 0.5*y1', 'dy2_dy1 = -0.5*x1'] exp2 = ['y1 = x2*x2*y2'] deriv2 = ['dy1_dx2 = 2.0*y2*x2', 'dy1_dy2 = x2*x2'] self.top.add('driver', Driv()) self.top.add('comp1', ExecCompWithDerivatives(exp1, deriv1)) self.top.add('comp2', ExecCompWithDerivatives(exp2, deriv2)) #self.top.add('comp1', ExecComp(exp1)) #self.top.add('comp2', ExecComp(exp2)) self.top.add('solver', BroydenSolver()) self.top.driver.workflow.add(['solver']) self.top.solver.workflow.add(['comp1', 'comp2']) self.top.connect('comp1.y2', 'comp2.y2') # Solver setup self.top.solver.add_parameter('comp1.y1', low=-1.e99, high=1.e99) self.top.solver.add_constraint('comp2.y1 = comp1.y1') # Top driver setup self.top.driver.differentiator = Analytic() self.top.driver.differentiator.mode = 'adjoint' obj = 'comp2.y1' self.top.driver.add_parameter('comp1.x1', low=-100., high=100., fd_step=.001) self.top.driver.add_parameter('comp2.x2', low=-100., high=100., fd_step=.0001) self.top.driver.add_objective(obj) self.top.comp1.x1 = 1.0 self.top.comp2.x2 = 1.0 self.top.run() self.top.driver.differentiator.calc_gradient() grad = self.top.driver.differentiator.get_gradient(obj) assert_rel_error(self, grad[0], 0.08660, .001)
def test_equation(self): top = set_as_top(Assembly()) top.add('precomp', ExecCompWithDerivatives(['y=x'], ['dy_dx = 1'])) top.precomp.x = 1.0 expr = ['y = 3.0*x*x -4.0*x'] deriv = ['dy_dx = 6.0*x -4.0'] top.add('comp', ExecCompWithDerivatives(expr, deriv)) top.driver.workflow.add(['comp']) top.add('driver', NewtonSolver()) top.driver.add_parameter('comp.x') top.driver.add_constraint('precomp.y - comp.y = 1.0 - 2.0') top.run() print top.comp.x, top.comp.y assert_rel_error(self, top.comp.x, -0.38742588, 1e-4)
def test_derivative_state_connection_external_solve_ProvideJ(self): model = set_as_top(Assembly()) model.add('comp', MyComp_Deriv_ProvideJ()) model.comp.add('c', Float(2.0, iotype="in", fd_step=.001)) model.add('comp2', ExecCompWithDerivatives(["y=2*x"], ["dy_dx=2"])) model.add('solver', BroydenSolver()) model.solver.workflow.add(['comp', 'comp2']) model.driver.workflow.add(['solver']) model.connect('comp.z', 'comp2.x') model.solver.add_parameter('comp.x', low=-100, high=100) model.solver.add_parameter('comp.y', low=-100, high=100) model.solver.add_parameter('comp.z', low=-100, high=100) model.solver.add_constraint('comp.res[0] = 0') model.solver.add_constraint('comp.res[1] = 0') model.solver.add_constraint('comp.res[2] = 0') model.comp.eval_only = True model.run() # print model.comp.x, model.comp.y, model.comp.z, model.comp.res J = model.driver.workflow.calc_gradient(inputs=['comp.c'], outputs=['comp2.y']) info = model.driver.workflow.get_implicit_info() # print info self.assertEqual( set(info[('_pseudo_0.out0', '_pseudo_1.out0', '_pseudo_2.out0')]), set([('comp.x', ), ('comp.y', ), ('comp.z', )])) self.assertEqual(len(info), 1) edges = model.driver.workflow._edges # print edges self.assertEqual(set(edges['@in0']), set(['comp.c'])) self.assertEqual(set(edges['comp2.y']), set(['@out0'])) assert_rel_error(self, J[0][0], -0.1666, 1e-3) model.driver.workflow.config_changed() J = model.driver.workflow.calc_gradient(inputs=['comp.c'], outputs=['comp2.y'], mode='adjoint') assert_rel_error(self, J[0][0], -0.1666, 1e-3) model.driver.workflow.config_changed() J = model.driver.workflow.calc_gradient(inputs=['comp.c'], outputs=['comp2.y'], mode='fd') assert_rel_error(self, J[0][0], -0.1666, 1e-3)
def test_three_comp_diamond_forward(self): self.top = set_as_top(Assembly()) exp1 = ['y1 = 50.0*x1', 'y2 = 1.0*x1'] deriv1 = ['dy1_dx1 = 50.0', 'dy2_dx1 = 1.0'] exp2 = ['y1 = 1.2*x1'] deriv2 = ['dy1_dx1 = 1.2'] exp3 = ['y1 = 100.0*x1*x2 + 30*x1 + 0.3*x2'] deriv3 = ['dy1_dx1 = 100.0*x2 + 30', 'dy1_dx2 = 100.0*x1 + 0.3'] self.top.add('comp1', ExecCompWithDerivatives(exp1, deriv1)) self.top.add('comp2', ExecCompWithDerivatives(exp2, deriv2)) self.top.add('comp3', ExecCompWithDerivatives(exp3, deriv3)) self.top.add('driver', SimpleDriver()) self.top.driver.workflow.add(['comp1', 'comp2', 'comp3']) self.top.connect('comp1.y1', 'comp2.x1') self.top.connect('comp1.y2', 'comp3.x1') self.top.connect('comp2.y1', 'comp3.x2') self.top.driver.add_parameter('comp1.x1', low=-100, high=100) self.top.driver.add_objective('comp3.y1') self.top.comp1.x1 = 2.0 self.top.run() J = self.top.driver.calc_gradient(inputs=['comp1.x1'], outputs=['comp3.y1'], mode='forward', return_format='dict') if self.comm.rank == 0: assert_rel_error(self, J['comp3.y1']['comp1.x1'][0][0], 24048.0, 0.0001)
def test_two_to_one_adjoint_bcast(self): top = set_as_top(Assembly()) exp1 = ["y = 3.0*x"] exp2 = ["y = -2.0*x"] exp3 = ["y = 5.0*x1 + 4.0*x2"] deriv1 = ["dy_dx = 3.0"] deriv2 = ["dy_dx = -2.0"] deriv3 = ["dy_dx1 = 5.0", "dy_dx2 = 4.0"] top.add('comp1', ExecCompWithDerivatives(exp1, deriv1)) top.add('comp2', ExecCompWithDerivatives(exp2, deriv2)) top.add('comp3', ExecCompWithDerivatives(exp3, deriv3)) top.add('driver', SimpleDriver()) top.driver.workflow.add(['comp1', 'comp2', 'comp3']) top.connect('comp1.y', 'comp3.x1') top.connect('comp2.y', 'comp3.x2') top.driver.add_parameter(('comp1.x', 'comp2.x'), low=-100, high=100) top.driver.add_constraint('comp3.y < 1000') top.run() J = top.driver.workflow.calc_gradient(mode='adjoint', return_format='dict') J = top.driver.workflow._system.get_combined_J(J) #from openmdao.util.dotgraph import plot_system_tree #plot_system_tree(top._system) collective_assert_rel_error(self, J['_pseudo_0.out0']['comp1.x'][0][0], 7.0, 0.0001)
def test_cascade_opt(self): raise SkipTest( "We currently don't allow a component instance in multiple workflows." ) top = set_as_top(Assembly()) eq = ['f = (x-3)**2 + x*y + (y+4)**2 - 3'] deriv = ['df_dx = 2.0*x - 6.0 + y', 'df_dy = 2.0*y + 8.0 + x'] top.add('comp', ExecCompWithDerivatives(eq, deriv)) top.add('driver', SimpleDriver()) top.add('opt1', SLSQPdriver()) top.add('opt2', SLSQPdriver()) top.opt1.workflow.add(['comp']) top.opt2.workflow.add(['comp']) top.driver.workflow.add(['opt1', 'opt2']) top.opt1.add_parameter('comp.x', low=-100, high=100) top.opt1.add_parameter('comp.y', low=-100, high=100) top.opt1.add_objective('comp.f') top.opt1.maxiter = 2 top.opt2.add_parameter('comp.x', low=-100, high=100) top.opt2.add_parameter('comp.y', low=-100, high=100) top.opt2.add_objective('comp.f') top.opt2.maxiter = 50 top.run() assert_rel_error(self, top.comp.x, 6.666309, 0.01) assert_rel_error(self, top.comp.y, -7.333026, 0.01) J = top.driver.calc_gradient(inputs=['comp.x', 'comp.y'], outputs=['comp.f']) edges = top.driver.workflow._edges print edges self.assertEqual(set(edges['@in0']), set(['~opt1.comp|x', '~opt2.comp|x'])) self.assertEqual(set(edges['@in1']), set(['~opt1.comp|y', '~opt2.comp|y'])) self.assertEqual(set(edges['~opt1.comp|f']), set(['@out0'])) self.assertEqual(set(edges['~opt2.comp|f']), set(['@out0']))
def test_derivative_state_connection_external_solve_ProvideJ(self): model = set_as_top(Assembly()) model.add('driver', SimpleDriver()) model.add('comp', MyComp_Deriv_ProvideJ()) model.comp.add('c', Float(2.0, iotype="in", fd_step=.001)) model.add('comp2', ExecCompWithDerivatives(["y=2*x"], ["dy_dx=2"])) model.add('solver', BroydenSolver()) model.solver.workflow.add(['comp', 'comp2']) model.driver.workflow.add(['solver']) model.connect('comp.z', 'comp2.x') model.solver.add_parameter('comp.x', low=-100, high=100) model.solver.add_parameter('comp.y', low=-100, high=100) model.solver.add_parameter('comp.z', low=-100, high=100) model.solver.add_constraint('comp.res[0] = 0') model.solver.add_constraint('comp.res[1] = 0') model.solver.add_constraint('comp.res[2] = 0') model.comp.eval_only = True model.run() #print model.comp.x, model.comp.y, model.comp.z, model.comp.res J = model.driver.calc_gradient(inputs=['comp.c'], outputs=['comp2.y'], mode='forward') assert_rel_error(self, J[0][0], -0.1666, 2e-3) J = model.driver.calc_gradient(inputs=['comp.c'], outputs=['comp2.y'], mode='adjoint') assert_rel_error(self, J[0][0], -0.1666, 2e-3) J = model.driver.calc_gradient(inputs=['comp.c'], outputs=['comp2.y'], mode='fd') assert_rel_error(self, J[0][0], -0.1666, 2e-3)
def test_execcomp_derivatives(self): exp1 = ['y1 = 2.0*x1 + x2*x2', 'y2 = 3.0*x1*x2'] deriv1 = [ 'dy1_dx1 = 2.0', 'dy1_dx2 = 2.0*x2', 'dy2_dx1 = 3.0*x2', 'dy2_dx2 = 3.0*x1' ] self.top.add('comp1', ExecCompWithDerivatives(exp1, deriv1)) self.top.driver.workflow.add('comp1') self.top.comp1.x1 = 3.0 self.top.comp1.x2 = 5.0 self.top.comp1.run() J = self.top.driver.workflow.calc_gradient( inputs=['comp1.x1', 'comp1.x2'], outputs=['comp1.y1', 'comp1.y2']) assert_rel_error(self, J[0, 0], 2.0, 0.0001) assert_rel_error(self, J[0, 1], 10.0, 0.0001) assert_rel_error(self, J[1, 0], 15.0, 0.0001) assert_rel_error(self, J[1, 1], 9.0, 0.0001) self.assertEqual(self.top.comp1.y2, 45.0)
def test_derivative_state_connection_internal_solve_apply_deriv(self): model = set_as_top(Assembly()) model.add('comp', MyComp_Deriv()) model.comp.add('c', Float(2.0, iotype="in", fd_step=.001)) model.add('comp2', ExecCompWithDerivatives(["y=2*x"], ["dy_dx=2"])) model.driver.workflow.add(['comp', 'comp2']) model.connect('comp.z', 'comp2.x') model.run() # print model.comp.x, model.comp.y, model.comp.z, model.comp.res J = model.driver.workflow.calc_gradient(inputs=['comp.c'], outputs=['comp2.y']) info = model.driver.workflow.get_implicit_info() # print info self.assertEqual(set(info[('comp.res', )]), set(['comp.x', 'comp.y', 'comp.z'])) self.assertEqual(len(info), 1) edges = model.driver.workflow._edges # print edges self.assertEqual(set(edges['@in0']), set(['comp.c'])) self.assertEqual(set(edges['comp2.y']), set(['@out0'])) assert_rel_error(self, J[0][0], -0.1666, 1e-3) model.driver.workflow.config_changed() J = model.driver.workflow.calc_gradient(inputs=['comp.c'], outputs=['comp2.y'], mode='adjoint') assert_rel_error(self, J[0][0], -0.1666, 1e-3) model.driver.workflow.config_changed() J = model.driver.workflow.calc_gradient(inputs=['comp.c'], outputs=['comp2.y'], mode='fd') assert_rel_error(self, J[0][0], -0.1666, 1e-3)
def test_execcomp_derivatives(self): exp1 = ['y1 = 2.0*x1 + x2*x2', 'y2 = 3.0*x1*x2'] deriv1 = [ 'dy1_dx1 = 2.0', 'dy1_dx2 = 2.0*x2', 'dy2_dx1 = 3.0*x2', 'dy2_dx2 = 3.0*x1' ] self.top.add('comp1', ExecCompWithDerivatives(exp1, deriv1)) self.top.comp1.x1 = 3.0 self.top.comp1.x2 = 5.0 self.top.comp1.run() self.top.comp1.calc_derivatives(first=True, second=False) self.assertEqual( self.top.comp1.derivatives.first_derivatives['y1']['x1'], 2.0) self.assertEqual( self.top.comp1.derivatives.first_derivatives['y1']['x2'], 10.0) self.assertEqual( self.top.comp1.derivatives.first_derivatives['y2']['x1'], 15.0) self.assertEqual( self.top.comp1.derivatives.first_derivatives['y2']['x2'], 9.0) self.assertEqual(self.top.comp1.y2, 45.0)
def test_diverge_converge_nondiff_comp3_forward(self): self.top = set_as_top(Assembly()) exp1 = ['y1 = 2.0*x1**2', 'y2 = 3.0*x1'] deriv1 = ['dy1_dx1 = 4.0*x1', 'dy2_dx1 = 3.0'] exp2 = ['y1 = 0.5*x1'] deriv2 = ['dy1_dx1 = 0.5'] exp3 = ['y1 = 3.5*x1'] deriv3 = ['dy1_dx1 = 3.5'] exp4 = ['y1 = x1 + 2.0*x2', 'y2 = 3.0*x1', 'y3 = x1*x2'] deriv4 = ['dy1_dx1 = 1.0', 'dy1_dx2 = 2.0', 'dy2_dx1 = 3.0', 'dy2_dx2 = 0.0', 'dy3_dx1 = x2', 'dy3_dx2 = x1'] exp5 = ['y1 = x1 + 3.0*x2 + 2.0*x3'] deriv5 = ['dy1_dx1 = 1.0', 'dy1_dx2 = 3.0', 'dy1_dx3 = 2.0'] self.top.add('driver', SimpleDriver()) self.top.add('comp1', ExecCompWithDerivatives(exp1, deriv1)) self.top.add('comp2', ExecCompWithDerivatives(exp2, deriv2)) self.top.add('comp3', ExecComp(exp3)) self.top.add('comp4', ExecCompWithDerivatives(exp4, deriv4)) self.top.add('comp5', ExecCompWithDerivatives(exp5, deriv5)) self.top.driver.workflow.add(['comp1', 'comp2', 'comp3', 'comp4', 'comp5']) self.top.connect('comp1.y1', 'comp2.x1') self.top.connect('comp1.y2', 'comp3.x1') self.top.connect('comp2.y1', 'comp4.x1') self.top.connect('comp3.y1', 'comp4.x2') self.top.connect('comp4.y1', 'comp5.x1') self.top.connect('comp4.y2', 'comp5.x2') self.top.connect('comp4.y3', 'comp5.x3') self.top.driver.add_parameter('comp1.x1', low=-100, high=100) self.top.driver.add_objective('comp5.y1') self.top.comp1.x1 = 2.0 self.top.run() J = self.top.driver.calc_gradient(inputs=['comp1.x1'], outputs=['comp5.y1'], mode='forward', return_format='dict') collective_assert_rel_error(self, J['comp5.y1']['comp1.x1'][0][0], 313.0, 0.0001)
def test_find_edges(self): # Verifies that we don't chain derivatives for inputs that are # connected in a parent assembly, but are not germain to our subassy # derivative. self.top = set_as_top(Assembly()) exp1 = ['y1 = 2.0*x1**2', 'y2 = 3.0*x1'] deriv1 = ['dy1_dx1 = 4.0*x1', 'dy2_dx1 = 3.0'] exp2 = ['y1 = 0.5*x1'] deriv2 = ['dy1_dx1 = 0.5'] exp3 = ['y1 = 3.5*x1'] deriv3 = ['dy1_dx1 = 3.5'] exp4 = ['y1 = x1 + 2.0*x2', 'y2 = 3.0*x1', 'y3 = x1*x2'] deriv4 = [ 'dy1_dx1 = 1.0', 'dy1_dx2 = 2.0', 'dy2_dx1 = 3.0', 'dy2_dx2 = 0.0', 'dy3_dx1 = x2', 'dy3_dx2 = x1' ] exp5 = ['y1 = x1 + 3.0*x2 + 2.0*x3'] deriv5 = ['dy1_dx1 = 1.0', 'dy1_dx2 = 3.0', 'dy1_dx3 = 2.0'] self.top.add('nest1', Assembly()) self.top.add('comp1', ExecCompWithDerivatives(exp1, deriv1)) self.top.nest1.add('driver', Driv()) self.top.nest1.add('comp2', ExecCompWithDerivatives(exp2, deriv2)) self.top.nest1.add('comp3', ExecCompWithDerivatives(exp3, deriv3)) self.top.nest1.add('comp4', ExecCompWithDerivatives(exp4, deriv4)) self.top.add('comp5', ExecCompWithDerivatives(exp5, deriv5)) self.top.driver.workflow.add(['comp1', 'nest1', 'comp5']) self.top.nest1.driver.workflow.add(['comp2', 'comp3', 'comp4']) self.top.nest1.driver.differentiator = ChainRule() obj = 'comp4.y1' con = 'comp3.y1-comp3.y1 > 0' self.top.nest1.driver.add_parameter('comp2.x1', low=-50., high=50., fd_step=.0001) self.top.nest1.driver.add_objective(obj) self.top.nest1.driver.add_constraint(con) self.top.nest1.add('real_c3_x1', Float(iotype='in', desc='I am really here')) self.top.nest1.add('real_c4_y2', Float(iotype='out', desc='I am really here')) self.top.connect('comp1.y1', 'nest1.comp2.x1') #self.top.connect('comp1.y1', 'nest1.comp2.x1') self.top.connect('comp1.y2', 'nest1.real_c3_x1') self.top.nest1.connect('real_c3_x1', 'comp3.x1') self.top.nest1.connect('comp2.y1', 'comp4.x1') self.top.nest1.connect('comp3.y1', 'comp4.x2') self.top.nest1.connect('comp4.y2', 'real_c4_y2') self.top.connect('nest1.real_c4_y2', 'comp5.x2') self.top.connect('nest1.comp4.y1', 'comp5.x1') self.top.connect('nest1.comp4.y3', 'comp5.x3') #self.top.connect('nest1.comp4.y2 + 1.0*nest1.comp4.y3', 'comp5.x3') self.top.comp1.x1 = 2.0 self.top.run() self.top.nest1.driver.differentiator.calc_gradient() edge_dict = self.top.nest1.driver.differentiator.edge_dicts[ 'nest1.driver'] self.assertTrue('x1' in edge_dict['comp2'][0]) self.assertTrue('x1' not in edge_dict['comp3'][0]) self.assertTrue('y1' in edge_dict['comp4'][1]) self.assertTrue('y2' not in edge_dict['comp4'][1])
def test_large_dataflow_mixed_finite_difference_three(self): self.top = set_as_top(Assembly()) exp1 = ['y1 = 2.0*x1**2', 'y2 = 3.0*x1'] deriv1 = ['dy1_dx1 = 4.0*x1', 'dy2_dx1 = 3.0'] exp2 = ['y1 = 0.5*x1'] deriv2 = ['dy1_dx1 = 0.5'] exp3 = ['y1 = 3.5*x1'] deriv3 = ['dy1_dx1 = 3.5'] exp4 = ['y1 = x1 + 2.0*x2', 'y2 = 3.0*x1', 'y3 = x1*x2'] deriv4 = [ 'dy1_dx1 = 1.0', 'dy1_dx2 = 2.0', 'dy2_dx1 = 3.0', 'dy2_dx2 = 0.0', 'dy3_dx1 = x2', 'dy3_dx2 = x1' ] exp5 = ['y1 = x1 + 3.0*x2 + 2.0*x3'] deriv5 = ['dy1_dx1 = 1.0', 'dy1_dx2 = 3.0', 'dy1_dx3 = 2.0'] self.top.add('comp1', ExecComp(exp1)) self.top.add('comp2', ExecCompWithDerivatives(exp2, deriv2)) self.top.add('comp3', ExecComp(exp3)) self.top.add('comp4', ExecCompWithDerivatives(exp4, deriv4)) self.top.add('comp5', ExecComp(exp5)) self.top.add('driver', Driv()) self.top.driver.workflow.add( ['comp1', 'comp2', 'comp3', 'comp4', 'comp5']) self.top.driver.differentiator = Analytic() obj = 'comp5.y1' con = 'comp5.y1-comp3.y1 > 0' self.top.driver.add_parameter('comp1.x1', low=-50., high=50., fd_step=.0001) self.top.driver.add_objective(obj) self.top.driver.add_constraint(con) self.top.connect('1.0*comp1.y1', 'comp2.x1') self.top.connect('comp1.y2', 'comp3.x1') self.top.connect('comp2.y1', 'comp4.x1') self.top.connect('comp3.y1', 'comp4.x2') self.top.connect('2.0*comp4.y1', 'comp5.x1') self.top.connect('2.0*comp4.y2', 'comp5.x2') self.top.connect('2.0*comp4.y3', 'comp5.x3') self.top.comp1.x1 = 2.0 self.top.run() self.top.driver.differentiator.calc_gradient() grad = self.top.driver.differentiator.get_gradient(obj) assert_rel_error(self, grad[0], 626.0, .001) grad = self.top.driver.differentiator.get_gradient( 'comp5.y1-comp3.y1>0') assert_rel_error(self, grad[0], -626.0 + 10.5, .001)
def test_large_dataflow_nested_assys(self): self.top = set_as_top(Assembly()) exp1 = ['y1 = 2.0*x1**2', 'y2 = 3.0*x1'] deriv1 = ['dy1_dx1 = 4.0*x1', 'dy2_dx1 = 3.0'] exp2 = ['y1 = 0.5*x1'] deriv2 = ['dy1_dx1 = 0.5'] exp3 = ['y1 = 3.5*x1'] deriv3 = ['dy1_dx1 = 3.5'] exp4 = ['y1 = x1 + 2.0*x2', 'y2 = 3.0*x1', 'y3 = x1*x2'] deriv4 = [ 'dy1_dx1 = 1.0', 'dy1_dx2 = 2.0', 'dy2_dx1 = 3.0', 'dy2_dx2 = 0.0', 'dy3_dx1 = x2', 'dy3_dx2 = x1' ] exp5 = ['y1 = x1 + 3.0*x2 + 2.0*x3'] deriv5 = ['dy1_dx1 = 1.0', 'dy1_dx2 = 3.0', 'dy1_dx3 = 2.0'] self.top.add('nest1', Assembly()) self.top.add('comp1', ExecCompWithDerivatives(exp1, deriv1)) self.top.nest1.add('comp2', ExecCompWithDerivatives(exp2, deriv2)) self.top.nest1.add('comp3', ExecCompWithDerivatives(exp3, deriv3)) self.top.nest1.add('comp4', ExecCompWithDerivatives(exp4, deriv4)) self.top.add('comp5', ExecCompWithDerivatives(exp5, deriv5)) self.top.add('driver', Driv()) self.top.driver.workflow.add(['comp1', 'nest1', 'comp5']) self.top.nest1.driver.workflow.add(['comp2', 'comp3', 'comp4']) self.top.driver.differentiator = Analytic() obj = 'comp5.y1' con = 'comp5.y1-nest1.comp3.y1 > 0' self.top.driver.add_parameter('comp1.x1', low=-50., high=50., fd_step=.0001) self.top.driver.add_objective(obj) self.top.driver.add_constraint(con) self.top.nest1.add('real_c2_x1', Float(iotype='in', desc='I am really here')) self.top.nest1.add('real_c3_x1', Float(iotype='in', desc='I am really here')) self.top.nest1.add('real_c4_y1', Float(iotype='out', desc='I am really here')) self.top.nest1.add('real_c4_y2', Float(iotype='out', desc='I am really here')) self.top.nest1.add('real_c4_y3', Float(iotype='out', desc='I am really here')) #self.top.connect('comp1.y1', 'nest1.comp2.x1') self.top.connect('comp1.y1', 'nest1.real_c2_x1') self.top.connect('comp1.y2', 'nest1.real_c3_x1') self.top.nest1.connect('real_c2_x1', 'comp2.x1') self.top.nest1.connect('real_c3_x1', 'comp3.x1') self.top.nest1.connect('comp2.y1', 'comp4.x1') self.top.nest1.connect('comp3.y1', 'comp4.x2') self.top.nest1.connect('comp4.y1', 'real_c4_y1') self.top.nest1.connect('comp4.y2', 'real_c4_y2') self.top.nest1.connect('comp4.y3', 'real_c4_y3') self.top.connect('nest1.real_c4_y1', 'comp5.x1') self.top.connect('nest1.real_c4_y2', 'comp5.x2') self.top.connect('nest1.real_c4_y3', 'comp5.x3') #self.top.connect('nest1.comp4.y1', 'comp5.x1') #self.top.connect('nest1.comp4.y3', 'comp5.x3') self.top.comp1.x1 = 2.0 self.top.run() self.top.driver.differentiator.calc_gradient() grad = self.top.driver.differentiator.get_gradient(obj) assert_rel_error(self, grad[0], 313.0, .001) grad = self.top.driver.differentiator.get_gradient( 'comp5.y1-nest1.comp3.y1>0') assert_rel_error(self, grad[0], -313.0 + 10.5, .001)
def test_input_as_output(self): top = set_as_top(Assembly()) top.add( 'comp1', ExecCompWithDerivatives(['y=2.0*x + 3.0*x2'], ['dy_dx = 2.0', 'dy_dx2 = 3.0'])) top.add('comp2', ExecCompWithDerivatives(['y=3.0*x'], ['dy_dx = 3.0'])) top.connect('comp1.y', 'comp2.x') top.add('driver', SimpleDriver()) top.driver.workflow.add(['comp1', 'comp2']) #top.driver.add_parameter('comp1.x', low=-100, high=100) top.driver.add_objective('comp1.y + comp2.y + 5*comp1.x') top.driver.gradient_options.lin_solver = 'petsc_ksp' objs = top.driver.get_objectives().values() obj = '%s.out0' % objs[0].pcomp_name top.comp1.x = 1.0 top.run() J = top.driver.calc_gradient(inputs=['comp1.x'], outputs=[obj], mode='forward') assert_rel_error(self, J[0, 0], 13.0, 0.0001) J = top.driver.calc_gradient(inputs=['comp1.x'], outputs=[obj], mode='fd') assert_rel_error(self, J[0, 0], 13.0, 0.0001) top.driver.run() J = top.driver.calc_gradient(inputs=['comp1.x'], outputs=[obj], mode='adjoint') assert_rel_error(self, J[0, 0], 13.0, 0.0001) J = top.driver.calc_gradient(inputs=['comp1.x', 'comp1.x2'], outputs=[obj], mode='forward') assert_rel_error(self, J[0, 0], 13.0, 0.0001) assert_rel_error(self, J[0, 1], 12.0, 0.0001) J = top.driver.calc_gradient(inputs=['comp1.x', 'comp1.x2'], outputs=[obj], mode='adjoint') assert_rel_error(self, J[0, 0], 13.0, 0.0001) assert_rel_error(self, J[0, 1], 12.0, 0.0001) J = top.driver.calc_gradient(inputs=[('comp1.x', ), ('comp1.x2', )], outputs=[obj], mode='forward') assert_rel_error(self, J[0, 0], 13.0, 0.0001) assert_rel_error(self, J[0, 1], 12.0, 0.0001) J = top.driver.calc_gradient(inputs=[('comp1.x', ), ('comp1.x2', )], outputs=[obj], mode='adjoint') assert_rel_error(self, J[0, 0], 13.0, 0.0001) assert_rel_error(self, J[0, 1], 12.0, 0.0001)