{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "5cdf6074",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:41:27.896148Z",
     "iopub.status.busy": "2026-10-02T14:41:27.895960Z",
     "iopub.status.idle": "2026-10-02T14:41:27.899927Z",
     "shell.execute_reply": "2026-10-02T14:41:27.899329Z"
    },
    "papermill": {
     "duration": 0.006491,
     "end_time": "2026-10-02T14:41:27.900884+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:41:27.894393+00:00",
     "status": "completed"
    },
    "tags": [
     "remove-input",
     "active-ipynb",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "try:\n",
    "    from openmdao.utils.notebook_utils import notebook_mode  # noqa: F401\n",
    "except ImportError:\n",
    "    !python -m pip install openmdao[notebooks]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "df0c90b4",
   "metadata": {
    "papermill": {
     "duration": 0.007047,
     "end_time": "2026-10-02T14:41:27.909176+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:41:27.902129+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "# InputResidsComp\n",
    "\n",
    "`InputResidsComp` is a specialized implementation of [ImplicitComponent](../../core_features/working_with_components/implicit_component.ipynb) 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.\n",
    "\n",
    "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**.\n",
    "\n",
    "`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."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "44857a3b",
   "metadata": {
    "papermill": {
     "duration": 0.000991,
     "end_time": "2026-10-02T14:41:27.911320+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:41:27.910329+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "## InputResidsComp Constructor\n",
    "\n",
    "The call signature for the `InputResidsComp` constructor is:\n",
    "\n",
    "```{eval-rst}\n",
    "    .. automethod:: openmdao.components.input_resids_comp.InputResidsComp.__init__()\n",
    "        :noindex:\n",
    "```"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "24202ab8",
   "metadata": {
    "papermill": {
     "duration": 0.001038,
     "end_time": "2026-10-02T14:41:27.913297+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:41:27.912259+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "## Example:  Single state vector, multiple equations of constraint\n",
    "\n",
    "The following example uses a InputResidsComp to implicitly solve the\n",
    "equations:\n",
    "\n",
    "\\begin{align}\n",
    "    x_0 + x_1 &= 5 \\\\\n",
    "    x_2 + x_3 &= 10 \\\\\n",
    "    x_0 &= x_3 \\\\\n",
    "    \\left\\Vert \\bar{x} \\right\\Vert &= 9\n",
    "\\end{align}\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "2651c7da",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:41:28.091098Z",
     "iopub.status.busy": "2026-10-02T14:41:28.090826Z",
     "iopub.status.idle": "2026-10-02T14:41:30.704772Z",
     "shell.execute_reply": "2026-10-02T14:41:30.704155Z"
    },
    "papermill": {
     "duration": 2.625493,
     "end_time": "2026-10-02T14:41:30.705393+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:41:28.079900+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[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\n",
      "[1790952090.683243] [runnervm8df0l:6588 :0]      ucp_worker.c:1412 UCX  ERROR uct_iface_open(ud_verbs/mana_0:1) failed: Input/output error\n",
      "NL: Newton 0 ; 8.00453567 1\n",
      "NL: Newton 1 ; 1.27590224 0.159397408\n",
      "NL: Newton 2 ; 0.167205529 0.020888848\n",
      "NL: Newton 3 ; 0.00698219699 0.000872280077\n",
      "NL: Newton 4 ; 1.504573e-05 1.87965056e-06\n",
      "NL: Newton 5 ; 7.05764336e-11 8.81705529e-12\n",
      "NL: Newton Converged\n",
      "6 Variables(s) in 'model'\n",
      "\n",
      "varname  val                  io      prom_name   \n",
      "-------  -------------------  ------  ------------\n",
      "exec\n",
      "  x      |9.0|                input   exec.x      \n",
      "         val:\n",
      "         array([2., 3., 8., 2.])\n",
      "  y      |0.0|                output  exec.y      \n",
      "         val:\n",
      "         array([0., 0., 0.])\n",
      "  z      [0.]                 output  exec.z      \n",
      "resids\n",
      "  res_0  |0.0|                input   resids.res_0\n",
      "         val:\n",
      "         array([0., 0., 0.])\n",
      "  res_1  [0.]                 input   resids.res_1\n",
      "  x      |9.0|                output  resids.x    \n",
      "         val:\n",
      "         array([2., 3., 8., 2.])\n",
      "\n",
      "\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[runnervm8df0l:06588] pml_ucx.c:313  Error: Failed to create UCP worker\n",
      "/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%).\n"
     ]
    }
   ],
   "source": [
    "import openmdao.api as om\n",
    "\n",
    "prob = om.Problem()\n",
    "\n",
    "bal = om.BalanceComp()\n",
    "bal.add_balance('x', use_mult=True)\n",
    "\n",
    "exec_comp = om.ExecComp(['y[0]=x[0] + x[1] - 5',\n",
    "                         'y[1]=x[2] + x[3] - 10',\n",
    "                         'y[2]=x[0] - x[3]',\n",
    "                         'z=dot(x, x)**0.5 - 9'],\n",
    "                        x={'shape': (4,)},\n",
    "                        y={'val': [1., 1., 1.]},\n",
    "                        z={'val': 2.})\n",
    "\n",
    "prob.model.add_subsystem(name='exec', subsys=exec_comp)\n",
    "resids = prob.model.add_subsystem(name='resids', subsys=om.InputResidsComp())\n",
    "\n",
    "resids.add_output('x', shape_by_conn=True)\n",
    "resids.add_input('res_0', shape_by_conn=True)\n",
    "resids.add_input('res_1', shape_by_conn=True)\n",
    "\n",
    "prob.model.connect('resids.x', 'exec.x')\n",
    "prob.model.connect('exec.y', 'resids.res_0')\n",
    "prob.model.connect('exec.z', 'resids.res_1')\n",
    "\n",
    "prob.model.linear_solver = om.DirectSolver(assemble_jac=True)\n",
    "prob.model.nonlinear_solver = om.NewtonSolver(solve_subsystems=False, maxiter=100, iprint=0)\n",
    "prob.set_solver_print(2)\n",
    "\n",
    "\n",
    "prob.setup()\n",
    "\n",
    "prob.set_val('resids.x', [1., 1., 10, 5])\n",
    "\n",
    "prob.final_setup()\n",
    "\n",
    "prob.run_model()\n",
    "\n",
    "prob.model.list_vars(print_arrays=True);\n"
   ]
  }
 ],
 "metadata": {
  "celltoolbar": "Tags",
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.14"
  },
  "orphan": true,
  "papermill": {
   "default_parameters": {},
   "duration": 3.985687,
   "end_time": "2026-10-02T14:41:31.221818+00:00",
   "environment_variables": {},
   "exception": null,
   "input_path": "/home/runner/work/OpenMDAO/OpenMDAO/openmdao/docs/openmdao_book/features/building_blocks/components/input_resids_comp.ipynb",
   "output_path": "/home/runner/work/OpenMDAO/OpenMDAO/openmdao/docs/_executed_book/features/building_blocks/components/input_resids_comp.ipynb",
   "parameters": {},
   "start_time": "2026-10-02T14:41:27.236131+00:00",
   "version": "2.7.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}