0

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']
Ry10
  • 87
  • 4

1 Answers1

1

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

Kenneth Moore
  • 2,167
  • 1
  • 9
  • 13
  • This is great thank you! I have found one more related bug. If you add an pbo output then it also fails when you finite difference across groups. Using the same example as above, if you add to the C1 component: self.add_output('pbo_output', val=0, pass_by_obj=True) then you get the error: File "/usr/local/lib/python2.7/site-packages/openmdao/core/system.py", line 590, in fd_jacobian jac[u_name, p_name][:, col] = result TypeError: float() argument must be a string or a number – Ry10 Feb 23 '16 at 17:06
  • I should have thought to check that! Anyway, I've amended my pull request to fix it on unknowns too. – Kenneth Moore Feb 23 '16 at 17:53