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_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)
def configure(self): driver = self.add('driver', DistributionCaseDriver()) self.add('driven', ArrayRosenSuzuki()) driver.workflow.add('driven') driver.distribution_generator = FiniteDifferenceGenerator(driver) driver.case_outputs = ['driven.rosen_suzuki'] driver.add_parameter('driven.x', low=-10., high=10., fd_step=[0.1, 0.01, 0.001, 0.0001])
def configure(self): self.add('driver', DistributionCaseDriver()) self.add('driven', RosenSuzukiComponent()) self.driver.workflow.add('driven') self.driver.distribution_generator = FiniteDifferenceGenerator(self.driver) self.driver.case_outputs = ['driven.rosen_suzuki'] self.driver.add_parameter("driven.x0", low=-10., high=10., fd_step = 0.1 ) self.driver.add_parameter("driven.x1", low=-10., high=10., fd_step = 0.01 ) self.driver.add_parameter("driven.x2", low=-10., high=10., fd_step = 0.001 ) self.driver.add_parameter("driven.x3", low=-10., high=10., fd_step = 0.0001 )
def test_invalid_input(self): model = Assembly() model.add('driver', DistributionCaseDriver()) model.add('driven', SimpleComponent()) model.driver.workflow.add('driven') model.driver.distribution_generator = FiniteDifferenceGenerator(model.driver) try: model.driver.add_parameter("driven.invalid", low=-10., high=10., fd_step = 0.1 ) except AttributeError as err: self.assertEqual(str(err), "driver: Can't add parameter 'driven.invalid' because it doesn't exist.")
def test_invalid_form(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) try: model.driver.distribution_generator.form = "INVALID_FORM" except ValueError, err: msg = ": Variable 'form' must be in ['CENTRAL', 'FORWARD', 'BACKWARD'], " \ "but a value of INVALID_FORM <type 'str'> was specified." self.assertEqual(str(err), msg)
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) try: model.driver.add_response('driven.invalid') except ValueError as err: self.assertEqual( str(err), "driver: Can't add response " "'driven.invalid' because of invalid variables" " 'driven.invalid'") else: self.fail('Expected ValueError')
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 __init__(self, *args, **kwargs): super(MyModel, self).__init__(*args, **kwargs) self.add('driver', DistributionCaseDriver()) self.add('driven', RosenSuzukiComponent()) self.driver.workflow.add('driven') self.driver.distribution_generator = FiniteDifferenceGenerator( self.driver) self.driver.case_outputs = ['driven.rosen_suzuki'] self.driver.add_parameter("driven.x0", low=-10., high=10., fd_step=0.1) self.driver.add_parameter("driven.x1", low=-10., high=10., fd_step=0.01) self.driver.add_parameter("driven.x2", low=-10., high=10., fd_step=0.001) self.driver.add_parameter("driven.x3", low=-10., high=10., fd_step=0.0001)
def __init__(self, model, comps, wrt, outs, stepsize=1.0e-6, order=1, form='CENTRAL'): ''' Takes a model and a list of component names in that model. The model is deepcopied to create a copy. All but the needed comps are removed from the model. model: Assembly Parent assembly of the components we want to finite difference. comps: list( string ) List of component names that we want to finite difference as a group. wrt: list( string ) List of variable paths to use as finite difference inputs. outs: list( string ) List of variable paths to return as outputs. stepsize: float Default stepsize to use. order: int Finite Difference order. Only first order is supported right now. form: string Choose from 'CENTRAL', 'FORWARD', and "BACKWARD'. Default is central differencing. ''' # Copy model. We need to null out the reference to the parent before # we copy. save_parent = model.parent model.parent = None try: self.model = deepcopy(model) finally: model.parent = save_parent # Get rid of the comps we don't need for item in self.model.list_containers(): if item not in comps + ['driver']: self.model.remove(item) # Remove all connections to the assembly boundary bdy_inputs = self.model.list_inputs() bdy_outputs = self.model.list_outputs() for conn in self.model.list_connections(): if conn[0] in bdy_inputs or conn[1] in bdy_outputs: self.model.disconnect(conn[0], conn[1]) # Distribution driver to drive the finite difference calculation self.model.add('driver', DistributionCaseDriver()) gen = FiniteDifferenceGenerator(self.model.driver) self.model.driver.distribution_generator = gen self.model.driver.workflow.add(comps) for item in wrt: self.model.driver.add_parameter(item, low=-1e99, high=1e99, fd_step=stepsize) self.model.driver.case_outputs = outs self.model.driver.ffd_order = 1 gen.num_parameters = len(wrt) gen.form = form gen.order = order # Save a reference to the original model so that we can increment the # execution counter as needed. self.copy_source = model # All execution counts should be reset to zero. for comp in self.model.driver.workflow.__iter__(): comp.exec_count = 0 comp.derivative_exec_count = 0