InputResidsComp#

InputResidsComp is a specialized implementation of ImplicitComponent that is intended to allow the user to simply add residuals to a system by treating any inputs to the components as the value of the associated residual.

Unlike BalanceComp, implicit outputs do not map one-to-one with the inputs. That is, the number of output variables for InputResidsComp does not have to match the number of input variables, but the total size of the inputs and outputs must be the same.

InputResidsComp can make it easier to convert an MDO problem from a “SAND” (simultaneous analysis and design) formumlation to an “MDF” (multiple design feasible) formulation by adding zero-valued equality constraints to it as inputs, and the associated design variables to it as implicit outputs.

InputResidsComp Constructor#

The call signature for the InputResidsComp constructor is:

InputResidsComp.__init__()[source]

Initialize the InputResidsComp.

Parameters:
**kwargsdict

Keyword arguments passed to the __init__ method of ImplicitComponent

Example: Single state vector, multiple equations of constraint#

The following example uses a InputResidsComp to implicitly solve the equations:

(1)#\[\begin{align} x_0 + x_1 &= 5 \\ x_2 + x_3 &= 10 \\ x_0 &= x_3 \\ \left\Vert \bar{x} \right\Vert &= 9 \end{align}\]
import openmdao.api as om

prob = om.Problem()

bal = om.BalanceComp()
bal.add_balance('x', use_mult=True)

exec_comp = om.ExecComp(['y[0]=x[0] + x[1] - 5',
                         'y[1]=x[2] + x[3] - 10',
                         'y[2]=x[0] - x[3]',
                         'z=dot(x, x)**0.5 - 9'],
                        x={'shape': (4,)},
                        y={'val': [1., 1., 1.]},
                        z={'val': 2.})

prob.model.add_subsystem(name='exec', subsys=exec_comp)
resids = prob.model.add_subsystem(name='resids', subsys=om.InputResidsComp())

resids.add_output('x', shape_by_conn=True)
resids.add_input('res_0', shape_by_conn=True)
resids.add_input('res_1', shape_by_conn=True)

prob.model.connect('resids.x', 'exec.x')
prob.model.connect('exec.y', 'resids.res_0')
prob.model.connect('exec.z', 'resids.res_1')

prob.model.linear_solver = om.DirectSolver(assemble_jac=True)
prob.model.nonlinear_solver = om.NewtonSolver(solve_subsystems=False, maxiter=100, iprint=0)
prob.set_solver_print(2)


prob.setup()

prob.set_val('resids.x', [1., 1., 10, 5])

prob.final_setup()

prob.run_model()

prob.model.list_vars(print_arrays=True);
[1790952090.682930] [runnervm8df0l:6588 :0]        ib_iface.c:1269 UCX  ERROR mana_0: iface 0x5593031d8470 failed to create UD QP TX wr:256 sge:6 inl:64 resp:0 RX wr:4096 sge:1 resp:0 failed: Operation not supported
[1790952090.683243] [runnervm8df0l:6588 :0]      ucp_worker.c:1412 UCX  ERROR uct_iface_open(ud_verbs/mana_0:1) failed: Input/output error
NL: Newton 0 ; 8.00453567 1
NL: Newton 1 ; 1.27590224 0.159397408
NL: Newton 2 ; 0.167205529 0.020888848
NL: Newton 3 ; 0.00698219699 0.000872280077
NL: Newton 4 ; 1.504573e-05 1.87965056e-06
NL: Newton 5 ; 7.05764336e-11 8.81705529e-12
NL: Newton Converged
6 Variables(s) in 'model'

varname  val                  io      prom_name   
-------  -------------------  ------  ------------
exec
  x      |9.0|                input   exec.x      
         val:
         array([2., 3., 8., 2.])
  y      |0.0|                output  exec.y      
         val:
         array([0., 0., 0.])
  z      [0.]                 output  exec.z      
resids
  res_0  |0.0|                input   resids.res_0
         val:
         array([0., 0., 0.])
  res_1  [0.]                 input   resids.res_1
  x      |9.0|                output  resids.x    
         val:
         array([2., 3., 8., 2.])
[runnervm8df0l:06588] pml_ucx.c:313  Error: Failed to create UCP worker
/home/runner/work/OpenMDAO/OpenMDAO/.pixi/envs/dev/lib/python3.13/site-packages/openmdao/utils/coloring.py:425: DerivativesWarning:'exec' <class ExecComp>: Coloring was deactivated.  Improvement of 0.0% was less than min allowed (5.0%).