Andrew
Andrew

Reputation: 175

Is there any way to get\list the unconnected inputs of an OpenMDAO group?

Considering the following problem

import openmdao.api as om


class Sys(om.Group):

    def setup(self):

        self.add_subsystem('sys1', om.ExecComp('v1 = a + b'), promotes=['*'])

        self.add_subsystem('sys2', om.ExecComp('v2 = v1 + c'), promotes=['*'])


if __name__ == '__main__':

    prob = om.Problem()
    model = prob.model

    comp = model.add_subsystem('comp', Sys(), promotes=['*'])

    prob.setup()
    prob.run_model()

    comp.list_inputs()

the list_inputs command gives the following

4 Input(s) in 'comp'

varname  val
-------  ----
sys1
  a      [1.]
  b      [1.]
sys2
  c      [1.]
  v1     [2.]

However we can clearly see that v1 in an 'internal' input to the system. If we were to attach this to an IndepVarComp or another system, we would not have to provide v1 since it is already internally connected.

Is there a function that can list the inputs that are unconnected or that must be provided to a Group?

Upvotes: 3

Views: 90

Answers (2)

Rob Falck
Rob Falck

Reputation: 2704

The next release of OpenMDAO (3.22.0) will feature an "Inputs report" (inputs.html) that is by-default generated in the reports subdirectory where you executed your model. One of the columns allows you to toggle the display to filter out inputs that are connected to an IndepVarComp (the default), not connected to an IndepVarComp, or to show all variables. This is currently active on the development branch of OpenMDAO now.

inputs.html

It's on our todo list to make an easier way of getting this information programmatically, but appending the following code to your example should work. The code first gets all outputs tagged with the openmdao:indep_var tag (which is special tag that OpenMDAO applies to IVC outputs). It then iterates recursively through the subsystems of the model. Within each subsystem, it looks at the connection information and sees if the source of a connection is one of the previously-detected IVC outputs.

    unconnected_inputs = []
    ivc_meta = prob.model.get_io_metadata(iotypes='output', tags='openmdao:indep_var', get_remote=True)
    for sys in prob.model.system_iter(include_self=True, recurse=True):
        if isinstance(sys, om.Group):
            for input, src in sys._conn_abs_in2out.items():
                if src in ivc_meta:
                    unconnected_inputs.append(input)
    print(unconnected_inputs)

Upvotes: 2

Justin Gray
Justin Gray

Reputation: 5710

Generally, I prefer to rely on the visual tools such as the N2.

However, here is a scriptable solution that I use on occation. Fair warning, it requires the use of one non-public attribute of system... but this is how I do it:

import openmdao.api as om


class Sys(om.Group):

    def setup(self):

        self.add_subsystem('sub_sys1', om.ExecComp('v1 = a + b'), promotes=['*'])

        self.add_subsystem('sub_sys2', om.ExecComp('v2 = v1 + c'), promotes=['*'])

if __name__ == '__main__':

    prob = om.Problem()
    model = prob.model

    comp = model.add_subsystem('comp', Sys(), promotes=['*'])

    prob.setup()
    prob.run_model()

    comp_inputs = prob.model.list_inputs(out_stream=None, prom_name=True)


    # filter the inputs into connected and unconnected sets
    connect_dict = comp._conn_global_abs_in2out
    unconnected_inputs = set()
    connected_inputs = set()
    for abs_name, in_data in comp_inputs:
        if abs_name in connect_dict and (not 'auto_ivc' in connect_dict[abs_name]):
            connected_inputs.add(in_data['prom_name'])
        else:
            unconnected_inputs.add(in_data['prom_name'])

    print(connected_inputs)
    print(unconnected_inputs)

Upvotes: 2

Related Questions