3

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?

Andrew
  • 163
  • 8
  • 1
    The way that I usually do this is to use the [`view_connections tool`](https://openmdao.org/newdocs/versions/latest/features/model_visualization/view_connections.html), which shows where the auto_ivc inputs are coming in and you can filter for them. Another option is to [use the N2 diagram](https://openmdao.org/newdocs/versions/latest/features/model_visualization/n2_basics/n2_basics.html) and look for orange variables, which means they're not connected to anything yet. I'm commenting instead of answering since this might not be exactly what you need, but might be helpful. – John Jasa Dec 13 '22 at 03:58

2 Answers2

2

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)
Justin Gray
  • 5,605
  • 1
  • 11
  • 16
2

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)
Rob Falck
  • 2,324
  • 16
  • 14