Ry10
Ry10

Reputation: 87

Error when finite differencing group with PBO

So I am trying to finite difference across a group and I'm running into the error

  File "/usr/local/lib/python2.7/site-packages/openmdao/core/system.py", line 531, in fd_jacobian
    target_input[idx] += step
TypeError: '_ByObjWrapper' object does not support indexing

I've traced it to the fact that it is trying to finite difference a variable that is pass_by_obj. Finite difference and pbo work when you finite difference across a component, but fails when you finite difference across a group. Here is an example:

import numpy as np
from openmdao.api import Group, Problem, Component, ScipyGMRES, ExecComp, IndepVarComp, NLGaussSeidel

class C1(Component):
    def __init__(self):
        super(C1, self).__init__()
        self.add_param('x', shape=1)
        self.add_param('B', val=0, pass_by_obj=True)
        self.add_output('y', shape=1)
        self.fd_options['force_fd'] = True

    def solve_nonlinear(self, params, unknowns, resids):
        unknowns['y'] = 4.0*params['x']*params['B']

class C2(Component):
    def __init__(self):
        super(C2, self).__init__()
        self.add_param('y', shape=1)
        self.add_output('z', shape=1)
        self.fd_options['force_fd'] = True

    def solve_nonlinear(self, params, unknowns, resids):
        unknowns['z'] = 2.0*params['y']

class FDGroup(Group):
    def __init__(self):
        super(FDGroup, self).__init__()
        self.add('c1', C1(), promotes=['*'])
        self.add('c2', C2(), promotes=['*'])
        self.fd_options['force_fd'] = True # Comment and then it works

class RootGroup(Group):
    def __init__(self):
        super(RootGroup, self).__init__()
        self.add('x', IndepVarComp('x', 0.0), promotes=['*'])
        self.add('B', IndepVarComp('B', 0, pass_by_obj=True), promotes=['*'])
        self.add('fd_group', FDGroup(), promotes=['*'])


p = Problem()
p.root = RootGroup()
p.setup(check=False)
p['x'] = 1.5
p['B'] = 2
p.run()
test_grad = open('test_grad.txt', 'w')
total_gradients = p.check_total_derivatives(out_stream=test_grad)

print
print "Derivative 1 - FWD", total_gradients['z', 'x']['J_fwd']
print "Derivative 1 - FD", total_gradients['z', 'x']['J_fd']

print p['z']

Upvotes: 0

Views: 67

Answers (1)

Kenneth Moore
Kenneth Moore

Reputation: 2202

Thank you for the bug report and the test. I've got a fix in for this. The pull request is up and will probably be accepted within a day, but if you want to try it early you can pull it down from my branch.

https://github.com/OpenMDAO/OpenMDAO/pull/482

Upvotes: 1

Related Questions