Connecting Variables

To cause data to flow between two systems in a model, we must connect at least one output variable from one system to at least one input variable from the other. If the variables have units defined, then the framework will automatically perform the conversion. We can also connect only part of an array output to an input by specifying the indices of the entries that we want.

To connect two variables within a model, use the connect function.

Group.connect(src_name, tgt_name, src_indices=None, flat_src_indices=None)[source]

Connect source src_name to target tgt_name in this namespace.

Parameters
src_namestr

Name of the source variable to connect.

tgt_namestr or [str, … ] or (str, …)

Name of the target variable(s) to connect.

src_indicesint or list of ints or tuple of ints or int ndarray or Iterable or None

The global indices of the source variable to transfer data from. The shapes of the target and src_indices must match, and form of the entries within is determined by the value of ‘flat_src_indices’.

flat_src_indicesbool

If True, each entry of src_indices is assumed to be an index into the flattened source. Otherwise it must be a tuple or list of size equal to the number of dimensions of the source.

Usage

1: Connect an output variable to an input variable, with an automatic unit conversion.

import numpy as np
import openmdao.api as om

p = om.Problem()

p.model.set_input_defaults('x', np.ones(5), units='ft')

exec_comp = om.ExecComp('y=sum(x)',
                        x={'val': np.zeros(5), 'units': 'inch'},
                        y={'units': 'inch'})

p.model.add_subsystem('comp1', exec_comp, promotes_inputs=['x'])

p.setup()
p.run_model()

print(p.get_val('x', units='ft'))
print(p.get_val('comp1.x'))
print(p.get_val('comp1.y'))
[1. 1. 1. 1. 1.]
[12. 12. 12. 12. 12.]
[60.]

2: Connect one output to many inputs.

p = om.Problem()

p.model.add_subsystem('C1', om.ExecComp('y=sum(x)*2.0', x=np.zeros(5)), promotes_inputs=['x'])
p.model.add_subsystem('C2', om.ExecComp('y=sum(x)*4.0', x=np.zeros(5)), promotes_inputs=['x'])
p.model.add_subsystem('C3', om.ExecComp('y=sum(x)*6.0', x=np.zeros(5)), promotes_inputs=['x'])

p.setup()
p.set_val('x', np.ones(5))
p.run_model()

print(p.get_val('C1.y'))
print(p.get_val('C2.y'))
print(p.get_val('C3.y'))
[10.]
[20.]
[30.]

3: Connect only part of an array output to an input of a smaller size.

p = om.Problem()

p.model.add_subsystem('indep', om.IndepVarComp('x', np.ones(5)))
p.model.add_subsystem('C1', om.ExecComp('y=sum(x)*2.0', x=np.zeros(3)))
p.model.add_subsystem('C2', om.ExecComp('y=sum(x)*4.0', x=np.zeros(2)))

# connect C1.x to the first 3 entries of indep.x
p.model.connect('indep.x', 'C1.x', src_indices=[0, 1, 2])

# connect C2.x to the last 2 entries of indep.x
# use -2 (same as 3 in this case) to show that negative indices work.
p.model.connect('indep.x', 'C2.x', src_indices=[-2, 4])

p.setup()
p.run_model()

print(p['C1.x'])
print(p['C1.y'])
print(p['C2.x'])
print(p['C2.y'])
[1. 1. 1.]
[6.]
[1. 1.]
[8.]

4: Connect only part of a non-flat array output to a non-flat array input.

p = om.Problem()

p.model.add_subsystem('indep', om.IndepVarComp('x', np.arange(12).reshape((4, 3))))
p.model.add_subsystem('C1', om.ExecComp('y=sum(x)*2.0', x=np.zeros((2, 2))))

# Connect C1.x to entries (0,0), (-1,1), (2,1), (1,1) of indep.x and give then a 2x2 shape.
# To do this, create 2x2 shaped arrays representing rows and columns. Note that the final
# src_indices is a tuple (not a list or array) containing the rows and cols arrays.
rows = [[0, -1],[2, 1]]
cols = [[0, 1], [1, 1]]
p.model.connect('indep.x', 'C1.x', src_indices=(rows, cols), flat_src_indices=False)

p.setup()
p.run_model()

print(p.get_val('indep.x'))
print(p.get_val('C1.x'))
print(p.get_val('C1.y'))
[[ 0.  1.  2.]
 [ 3.  4.  5.]
 [ 6.  7.  8.]
 [ 9. 10. 11.]]
[[ 0. 10.]
 [ 7.  4.]]
[42.]