0

Is unit conversion with pass_by_obj supported in OpenMDAO 1.4? I have a small repro case:

from openmdao.api import Component, Problem, Group, IndepVarComp

pass_by_obj=True

class PassByObjParaboloid(Component):
    def __init__(self):
        super(PassByObjParaboloid, self).__init__()
        self.fd_options['force_fd'] = True

        self.add_param('x', val=1.0, pass_by_obj=pass_by_obj, units='mm')

        self.add_output('f_xy', val=0.0)

    def solve_nonlinear(self, params, unknowns, resids):
        print params['x']
        assert params['x'] == 1000.0

        unknowns['f_xy'] = params['x']

    def linearize(self, params, unknowns, resids):
        raise Exception()

top = Problem()

root = top.root = Group()

root.add('p1', IndepVarComp('x', 1.0, pass_by_obj=pass_by_obj, units='m'))
root.add('p', PassByObjParaboloid())

root.connect('p1.x', 'p.x')

top.setup()
top.run()

With pass_by_obj=True, the assert fails. top.setup() reports:

Unit Conversions
p1.x -> p.x : m -> mm

So I'd expect the unit conversion to be done.

Kevin Smyth
  • 1,892
  • 21
  • 22

1 Answers1

2

OpenMDAO currently does not support automatic unit conversions for pass_by_obj variables. When designing OpenMDAO, we didn't intend for floating point data to be transferred using pass_by_obj. We only added pass_by_obj to handle other kinds of variables. We should fix the diagnostic output of setup so that it doesn't list unit conversions that don't actually happen. I'll put a story in for that.

Justin Gray
  • 5,605
  • 1
  • 11
  • 16
Bret Naylor
  • 704
  • 3
  • 8
  • We should make it a hard error if units are declared on pbo variables. – Kenneth Moore Jan 14 '16 at 17:14
  • Thanks for the quick response. This is not great for us, since we have Components that vary the shape of their unknowns based on the parameters. So we need `pass_by_obj` for that. Do you have a suggestion on how to do unit conversion in this case? – Kevin Smyth Jan 14 '16 at 17:58
  • There are a couple of options. One is for you to manually insert a conversion component. I think a better option would be to find a way to do this without pass_by_obj. One way you could do that is to zero-pad your shape-changing unknown and then pass an additional index param that contains the usable width so that you can fill it with calculated values up to the width. It is ideal to use the float data passage system as much as possible so you can take advantage of features such as unit conversion and analytic gradients. – Kenneth Moore Jan 14 '16 at 19:19
  • We've decided to add the unit-conversion for PBO Float and FloatArray types to support your models. It should get done in the next several weeks. Its a reasonable thing to do to use PBO objects if your arrays are changing size. However note that this is only going to be allowed you're not trying to compute analytic derivatives. If you do compute analytic derivatives across PBO connections you'll get a very wrong answer! – Justin Gray Jan 16 '16 at 14:53
  • 1
    Thanks gents. For reference, https://github.com/OpenMDAO/OpenMDAO/pull/449 is the PR for this – Kevin Smyth Jan 21 '16 at 22:46
  • The feature has been merged into the master branch on this commit: https://github.com/OpenMDAO/OpenMDAO/commit/498768e5884e63b3449490167955e4219c5f9e3b – Justin Gray Jan 25 '16 at 19:12