0

I am just playing around with the Paraboloid tutorial in OpenMDAO. I tried something simple, basically changing the input values to the Paraboloid component. See the following code. When I run it though, it will print the same result as if nothing happened. So what is going on? if I have a group, how would I modify the inputs?

from __future__ import print_function


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

class Paraboloid(Component):
    """ Evaluates the equation f(x,y) = (x-3)^2 + xy + (y+4)^2 - 3 """

    def __init__(self):
        super(Paraboloid, self).__init__()

        self.add_param('x', val=0.0)
        self.add_param('y', val=0.0)

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

    def solve_nonlinear(self, params, unknowns, resids):
        """f(x,y) = (x-3)^2 + xy + (y+4)^2 - 3
        """

        x = params['x']
        y = params['y']

        unknowns['f_xy'] = (x-3.0)**2 + x*y + (y+4.0)**2 - 3.0

    def linearize(self, params, unknowns, resids):
        """ Jacobian for our paraboloid."""

        x = params['x']
        y = params['y']
        J = {}

        J['f_xy', 'x'] = 2.0*x - 6.0 + y
        J['f_xy', 'y'] = 2.0*y + 8.0 + x
        return J

if __name__ == "__main__":

    top = Problem()

    root = top.root = Group()

    root.add('p1', IndepVarComp('x', 3.0))
    root.add('p2', IndepVarComp('y', -4.0))
    root.add('p', Paraboloid())

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


    root.p1.x=3.0;
    root.p2.y=-4.0;
    top.setup()
    top.run()
    print(root.p.unknowns['f_xy'])

    root.p1.x=5.0;
    root.p2.y=5.0;
    top.setup()
    top.run()
    print(root.p.unknowns['f_xy'])
Mike McWilliam
  • 166
  • 1
  • 9
  • I managed to modify the input values to this system by setting the values with the following code: top.setup() root.p1.unknowns['x']=5.0; root.p2.unknowns['y']=5.0; top.run() print(root.p.unknowns['f_xy']) – Mike McWilliam Feb 16 '16 at 12:50
  • It seems OpenMDAO ignores the data members. When an output is added, it is not a member, but a merely a string for a dictionary key that needs to be populated when the component is accessed. It seems IndepVarComp builds its dictionary in the set-up with the default value, that is why it was ignored before. – Mike McWilliam Feb 16 '16 at 12:51
  • I question whether or not I am setting the values correctly? Is there a get() and set() method that I should use instead? Does OpenMDAO keep track of changes to the input for other purposes? – Mike McWilliam Feb 16 '16 at 12:52

1 Answers1

0

You have to call setup() before you can set any values. After that you set them via a dictionary like access from the problem instance. For your sample code it should look like:

top.setup()
top['p1.x'] = 3.
top['p2.y'] = 4.
top.run()
print(top['p.f_xy'])

top['p1.x'] = 10.
top['p2.y'] = 10.
top.run()
print(top['p.f_xy'])

When I run this model with the adjusted script I get:

##############################################
Setup: Checking for potential issues...

No recorders have been specified, so no data will be saved.

Setup: Check complete.
##############################################

73.0
342.0
Justin Gray
  • 5,605
  • 1
  • 11
  • 16
  • It seems that only problems can set variables then... so it is the problem that keeps track of the input/output state, if an input is modified at the problem level, the system know and thus knows to re-calculate all the outputs dependent on the input. Is that correct? – Mike McWilliam Feb 16 '16 at 13:59
  • That is not correct. When you change inputs you have to call run() for it to recalculate base on the new input values – Justin Gray Feb 16 '16 at 14:04
  • I am just trying to understand the architecture a little. It seems that the components do not store the inputs/outputs as members. The whole point to add_param and add_output is just to inform the openMDAO system about the I/O. Then it is the Group that manages the execution of all the components. Is that correct? – Mike McWilliam Feb 16 '16 at 14:05
  • Is the order of execution in the group determined by the IO graph (assuming there are no implicit relations)? or is it determined by the order components are added to the group? – Mike McWilliam Feb 16 '16 at 14:09
  • By default, the execution order is determined by the connectivity graph. However, you can set the order explicitly by calling `set_order(["comp1", "comp2"])` method on any group. – Justin Gray Feb 16 '16 at 15:41