{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "c46d8a46",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:41:14.889916Z",
     "iopub.status.busy": "2026-10-02T14:41:14.889653Z",
     "iopub.status.idle": "2026-10-02T14:41:14.894947Z",
     "shell.execute_reply": "2026-10-02T14:41:14.894256Z"
    },
    "papermill": {
     "duration": 0.008804,
     "end_time": "2026-10-02T14:41:14.895894+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:41:14.887090+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]"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "428a4cb0",
   "metadata": {
    "papermill": {
     "duration": 0.190826,
     "end_time": "2026-10-02T14:41:15.088176+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:41:14.897350+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "# EQConstraintComp\n",
    "\n",
    "`EQConstraintComp` is a specialized component that provides a simple way to implement\n",
    "equality constraints.\n",
    "\n",
    "You can add one or more outputs to an `EQConstraintComp` that compute the difference\n",
    "between a pair of input values for the purposes of driving the two inputs to equality. It\n",
    "computes the output value as:\n",
    "\n",
    "$$\n",
    "  name_{output} = \\frac{ name_{mult} \\times name_{lhs} - name_{rhs} }{f_{norm}(name_{rhs})}\n",
    "$$\n",
    "\n",
    "The normalization function $f_{norm}(name_{rhs})$ takes one of the following forms:\n",
    "\n",
    "$$\n",
    "  f_{norm}(name_{rhs}) =\n",
    "  \\begin{cases}\n",
    "    \\left| name_{rhs} \\right|,      & \\text{if normalize and } \\left| name_{rhs} \\right| \\geq 2 \\\\\n",
    "    0.25 name_{rhs}^2 + 1,      & \\text{if normalize and } \\left| name_{rhs} \\right| < 2 \\\\\n",
    "    1,      & \\text{if not normalize}\n",
    "  \\end{cases}\n",
    "$$ \n",
    "\n",
    "The following inputs and outputs are associated with each output variable.\n",
    "\n",
    "```{eval-rst}\n",
    "    =========== ======= ====================================================\n",
    "    Name        I/O     Description\n",
    "    =========== ======= ====================================================\n",
    "    {name}      output  output variable\n",
    "    lhs:{name}  input   left-hand side of difference equation\n",
    "    rhs:{name}  input   right-hand side of difference equation\n",
    "    mult:{name} input   left-hand side multiplier of difference equation\n",
    "    =========== ======= ====================================================\n",
    "```\n",
    "\n",
    "The default value for the `rhs:{name}` input can be set to via the\n",
    "`rhs_val` argument (see arguments below). If the rhs value is fixed (e.g. 0),\n",
    "then the input can be left unconnected. The `lhs:{name}` input must always have\n",
    "something connected to it.\n",
    "\n",
    "The multiplier is optional and will default to 1.0 if not connected.\n",
    "\n",
    "`EQConstraintComp` supports vectorized outputs. Simply provide a default\n",
    "value or shape when adding the output that reflects the correct shape.\n",
    "\n",
    "You can provide the arguments to create an output variable when instantiating an\n",
    "`EQConstraintComp` or you can use the ``add_eq_output`` method to create one\n",
    "or more outputs after instantiation.  The constructor accepts all the same arguments\n",
    "as the ``add_eq_output`` method:\n",
    "\n",
    "```{eval-rst}\n",
    "    .. automethod:: openmdao.components.eq_constraint_comp.EQConstraintComp.add_eq_output\n",
    "       :noindex:\n",
    "```\n",
    "\n",
    "Note that the `kwargs` arguments can include any of the keyword arguments normally available\n",
    "when creating an output variable with the\n",
    "`add_output` method of a [Component](../../../_srcdocs/packages/core/component).\n",
    "\n",
    "\n",
    "## Example: Sellar IDF\n",
    "\n",
    "The following example shows an Individual Design Feasible (IDF) architecture for the\n",
    "[Sellar](../../../basic_user_guide/multidisciplinary_optimization/sellar.ipynb) problem that demonstrates the use of an `EQConstraintComp`.\n",
    "\n",
    "In IDF, the direct coupling between the disciplines is removed and the coupling variables\n",
    "are added to the optimizer’s design variables. The algorithm calls for two new equality\n",
    "constraints that enforce the coupling between the disciplines. This ensures that the final\n",
    "optimized solution is feasible, though it is achieved through the optimizer instead of\n",
    "using a solver.  The two new equality constraints are implemented in this example with\n",
    "an `EQConstraintComp`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "c41a0629",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:41:15.233827Z",
     "iopub.status.busy": "2026-10-02T14:41:15.233561Z",
     "iopub.status.idle": "2026-10-02T14:41:16.512795Z",
     "shell.execute_reply": "2026-10-02T14:41:16.512042Z"
    },
    "papermill": {
     "duration": 1.382023,
     "end_time": "2026-10-02T14:41:16.513599+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:41:15.131576+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import openmdao.api as om\n",
    "from openmdao.test_suite.components.sellar import SellarDis1withDerivatives, SellarDis2withDerivatives\n",
    "\n",
    "\n",
    "class SellarIDF(om.Group):\n",
    "    \"\"\"\n",
    "    Individual Design Feasible (IDF) architecture for the Sellar problem.\n",
    "    \"\"\"\n",
    "    def setup(self):\n",
    "        # construct the Sellar model with `y1` and `y2` as independent variables\n",
    "\n",
    "        self.set_input_defaults('x', 5.)\n",
    "        self.set_input_defaults('y1', 5.)\n",
    "        self.set_input_defaults('y2', 5.)\n",
    "        self.set_input_defaults('z', np.array([2., 0.]))\n",
    "\n",
    "        self.add_subsystem('d1', SellarDis1withDerivatives(), promotes_inputs=['x', 'z', 'y2'])\n",
    "        self.add_subsystem('d2', SellarDis2withDerivatives(), promotes_inputs=['y1', 'z'])\n",
    "\n",
    "        self.add_subsystem('obj_cmp', om.ExecComp('obj = x**2 + z[1] + y1 + exp(-y2)',\n",
    "                           x=0., z=np.array([0., 0.])), promotes_inputs=['x', 'z', 'y1', 'y2'])\n",
    "\n",
    "        self.add_subsystem('con_cmp1', om.ExecComp('con1 = 3.16 - y1'), promotes_inputs=['y1'])\n",
    "        self.add_subsystem('con_cmp2', om.ExecComp('con2 = y2 - 24.0'), promotes_inputs=['y2'])\n",
    "\n",
    "        # rather than create a cycle by connecting d1.y1 to d2.y1 and d2.y2 to d1.y2\n",
    "        # we will constrain y1 and y2 to be equal for the two disciplines\n",
    "\n",
    "        equal = om.EQConstraintComp()\n",
    "        self.add_subsystem('equal', equal, promotes_inputs=[('lhs:y1', 'y1'), ('lhs:y2', 'y2')])\n",
    "\n",
    "        equal.add_eq_output('y1', add_constraint=True)\n",
    "        equal.add_eq_output('y2', add_constraint=True)\n",
    "\n",
    "        self.connect('d1.y1', 'equal.rhs:y1')\n",
    "        self.connect('d2.y2', 'equal.rhs:y2')\n",
    "\n",
    "        # the driver will effectively solve the cycle\n",
    "        # by satisfying the equality constraints\n",
    "\n",
    "        self.add_design_var('x', lower=0., upper=5.)\n",
    "        self.add_design_var('y1', lower=0., upper=5.)\n",
    "        self.add_design_var('y2', lower=0., upper=5.)\n",
    "        self.add_design_var('z', lower=np.array([-5., 0.]), upper=np.array([5., 5.]))\n",
    "        self.add_objective('obj_cmp.obj')\n",
    "        self.add_constraint('con_cmp1.con1', upper=0.)\n",
    "        self.add_constraint('con_cmp2.con2', upper=0.)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "a8dc713d",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:41:16.516797Z",
     "iopub.status.busy": "2026-10-02T14:41:16.516506Z",
     "iopub.status.idle": "2026-10-02T14:41:17.252097Z",
     "shell.execute_reply": "2026-10-02T14:41:17.251305Z"
    },
    "papermill": {
     "duration": 0.737986,
     "end_time": "2026-10-02T14:41:17.252815+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:41:16.514829+00:00",
     "status": "completed"
    },
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [
    {
     "data": {
      "application/papermill.record/text/html": "<style>pre { line-height: 125%; }\ntd.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\nspan.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\ntd.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\nspan.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\n.output_html .hll { background-color: #ffffcc }\n.output_html { background: #f8f8f8; }\n.output_html .c { color: #3D7B7B; font-style: italic } /* Comment */\n.output_html .err { border: 1px solid #F00 } /* Error */\n.output_html .k { color: #008000; font-weight: bold } /* Keyword */\n.output_html .o { color: #666 } /* Operator */\n.output_html .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */\n.output_html .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */\n.output_html .cp { color: #9C6500 } /* Comment.Preproc */\n.output_html .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */\n.output_html .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */\n.output_html .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */\n.output_html .gd { color: #A00000 } /* Generic.Deleted */\n.output_html .ge { font-style: italic } /* Generic.Emph */\n.output_html .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */\n.output_html .gr { color: #E40000 } /* Generic.Error */\n.output_html .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n.output_html .gi { color: #008400 } /* Generic.Inserted */\n.output_html .go { color: #717171 } /* Generic.Output */\n.output_html .gp { color: #000080; font-weight: bold } /* Generic.Prompt */\n.output_html .gs { font-weight: bold } /* Generic.Strong */\n.output_html .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n.output_html .gt { color: #04D } /* Generic.Traceback */\n.output_html .kc { color: #008000; font-weight: bold } /* Keyword.Constant */\n.output_html .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */\n.output_html .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */\n.output_html .kp { color: #008000 } /* Keyword.Pseudo */\n.output_html .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */\n.output_html .kt { color: #B00040 } /* Keyword.Type */\n.output_html .m { color: #666 } /* Literal.Number */\n.output_html .s { color: #BA2121 } /* Literal.String */\n.output_html .na { color: #687822 } /* Name.Attribute */\n.output_html .nb { color: #008000 } /* Name.Builtin */\n.output_html .nc { color: #00F; font-weight: bold } /* Name.Class */\n.output_html .no { color: #800 } /* Name.Constant */\n.output_html .nd { color: #A2F } /* Name.Decorator */\n.output_html .ni { color: #717171; font-weight: bold } /* Name.Entity */\n.output_html .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */\n.output_html .nf { color: #00F } /* Name.Function */\n.output_html .nl { color: #767600 } /* Name.Label */\n.output_html .nn { color: #00F; font-weight: bold } /* Name.Namespace */\n.output_html .nt { color: #008000; font-weight: bold } /* Name.Tag */\n.output_html .nv { color: #19177C } /* Name.Variable */\n.output_html .ow { color: #A2F; font-weight: bold } /* Operator.Word */\n.output_html .w { color: #BBB } /* Text.Whitespace */\n.output_html .mb { color: #666 } /* Literal.Number.Bin */\n.output_html .mf { color: #666 } /* Literal.Number.Float */\n.output_html .mh { color: #666 } /* Literal.Number.Hex */\n.output_html .mi { color: #666 } /* Literal.Number.Integer */\n.output_html .mo { color: #666 } /* Literal.Number.Oct */\n.output_html .sa { color: #BA2121 } /* Literal.String.Affix */\n.output_html .sb { color: #BA2121 } /* Literal.String.Backtick */\n.output_html .sc { color: #BA2121 } /* Literal.String.Char */\n.output_html .dl { color: #BA2121 } /* Literal.String.Delimiter */\n.output_html .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */\n.output_html .s2 { color: #BA2121 } /* Literal.String.Double */\n.output_html .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */\n.output_html .sh { color: #BA2121 } /* Literal.String.Heredoc */\n.output_html .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */\n.output_html .sx { color: #008000 } /* Literal.String.Other */\n.output_html .sr { color: #A45A77 } /* Literal.String.Regex */\n.output_html .s1 { color: #BA2121 } /* Literal.String.Single */\n.output_html .ss { color: #19177C } /* Literal.String.Symbol */\n.output_html .bp { color: #008000 } /* Name.Builtin.Pseudo */\n.output_html .fm { color: #00F } /* Name.Function.Magic */\n.output_html .vc { color: #19177C } /* Name.Variable.Class */\n.output_html .vg { color: #19177C } /* Name.Variable.Global */\n.output_html .vi { color: #19177C } /* Name.Variable.Instance */\n.output_html .vm { color: #19177C } /* Name.Variable.Magic */\n.output_html .il { color: #666 } /* Literal.Number.Integer.Long */</style><div class=\"highlight\"><pre><span></span><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">SellarIDF</span><span class=\"p\">(</span><span class=\"n\">om</span><span class=\"o\">.</span><span class=\"n\">Group</span><span class=\"p\">):</span>\n<span class=\"w\">    </span><span class=\"sd\">&quot;&quot;&quot;</span>\n<span class=\"sd\">    Individual Design Feasible (IDF) architecture for the Sellar problem.</span>\n<span class=\"sd\">    &quot;&quot;&quot;</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">setup</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"c1\"># construct the Sellar model with `y1` and `y2` as independent variables</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">set_input_defaults</span><span class=\"p\">(</span><span class=\"s1\">&#39;x&#39;</span><span class=\"p\">,</span> <span class=\"mf\">5.</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">set_input_defaults</span><span class=\"p\">(</span><span class=\"s1\">&#39;y1&#39;</span><span class=\"p\">,</span> <span class=\"mf\">5.</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">set_input_defaults</span><span class=\"p\">(</span><span class=\"s1\">&#39;y2&#39;</span><span class=\"p\">,</span> <span class=\"mf\">5.</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">set_input_defaults</span><span class=\"p\">(</span><span class=\"s1\">&#39;z&#39;</span><span class=\"p\">,</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">2.</span><span class=\"p\">,</span> <span class=\"mf\">0.</span><span class=\"p\">]))</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_subsystem</span><span class=\"p\">(</span><span class=\"s1\">&#39;d1&#39;</span><span class=\"p\">,</span> <span class=\"n\">SellarDis1withDerivatives</span><span class=\"p\">(),</span> <span class=\"n\">promotes_inputs</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"s1\">&#39;x&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;z&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;y2&#39;</span><span class=\"p\">])</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_subsystem</span><span class=\"p\">(</span><span class=\"s1\">&#39;d2&#39;</span><span class=\"p\">,</span> <span class=\"n\">SellarDis2withDerivatives</span><span class=\"p\">(),</span> <span class=\"n\">promotes_inputs</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"s1\">&#39;y1&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;z&#39;</span><span class=\"p\">])</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_subsystem</span><span class=\"p\">(</span><span class=\"s1\">&#39;obj_cmp&#39;</span><span class=\"p\">,</span> <span class=\"n\">om</span><span class=\"o\">.</span><span class=\"n\">ExecComp</span><span class=\"p\">(</span><span class=\"s1\">&#39;obj = x**2 + z[1] + y1 + exp(-y2)&#39;</span><span class=\"p\">,</span>\n                           <span class=\"n\">x</span><span class=\"o\">=</span><span class=\"mf\">0.</span><span class=\"p\">,</span> <span class=\"n\">z</span><span class=\"o\">=</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">0.</span><span class=\"p\">,</span> <span class=\"mf\">0.</span><span class=\"p\">])),</span> <span class=\"n\">promotes_inputs</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"s1\">&#39;x&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;z&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;y1&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;y2&#39;</span><span class=\"p\">])</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_subsystem</span><span class=\"p\">(</span><span class=\"s1\">&#39;con_cmp1&#39;</span><span class=\"p\">,</span> <span class=\"n\">om</span><span class=\"o\">.</span><span class=\"n\">ExecComp</span><span class=\"p\">(</span><span class=\"s1\">&#39;con1 = 3.16 - y1&#39;</span><span class=\"p\">),</span> <span class=\"n\">promotes_inputs</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"s1\">&#39;y1&#39;</span><span class=\"p\">])</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_subsystem</span><span class=\"p\">(</span><span class=\"s1\">&#39;con_cmp2&#39;</span><span class=\"p\">,</span> <span class=\"n\">om</span><span class=\"o\">.</span><span class=\"n\">ExecComp</span><span class=\"p\">(</span><span class=\"s1\">&#39;con2 = y2 - 24.0&#39;</span><span class=\"p\">),</span> <span class=\"n\">promotes_inputs</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"s1\">&#39;y2&#39;</span><span class=\"p\">])</span>\n\n        <span class=\"c1\"># rather than create a cycle by connecting d1.y1 to d2.y1 and d2.y2 to d1.y2</span>\n        <span class=\"c1\"># we will constrain y1 and y2 to be equal for the two disciplines</span>\n\n        <span class=\"n\">equal</span> <span class=\"o\">=</span> <span class=\"n\">om</span><span class=\"o\">.</span><span class=\"n\">EQConstraintComp</span><span class=\"p\">()</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_subsystem</span><span class=\"p\">(</span><span class=\"s1\">&#39;equal&#39;</span><span class=\"p\">,</span> <span class=\"n\">equal</span><span class=\"p\">,</span> <span class=\"n\">promotes_inputs</span><span class=\"o\">=</span><span class=\"p\">[(</span><span class=\"s1\">&#39;lhs:y1&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;y1&#39;</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"s1\">&#39;lhs:y2&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;y2&#39;</span><span class=\"p\">)])</span>\n\n        <span class=\"n\">equal</span><span class=\"o\">.</span><span class=\"n\">add_eq_output</span><span class=\"p\">(</span><span class=\"s1\">&#39;y1&#39;</span><span class=\"p\">,</span> <span class=\"n\">add_constraint</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n        <span class=\"n\">equal</span><span class=\"o\">.</span><span class=\"n\">add_eq_output</span><span class=\"p\">(</span><span class=\"s1\">&#39;y2&#39;</span><span class=\"p\">,</span> <span class=\"n\">add_constraint</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">connect</span><span class=\"p\">(</span><span class=\"s1\">&#39;d1.y1&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;equal.rhs:y1&#39;</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">connect</span><span class=\"p\">(</span><span class=\"s1\">&#39;d2.y2&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;equal.rhs:y2&#39;</span><span class=\"p\">)</span>\n\n        <span class=\"c1\"># the driver will effectively solve the cycle</span>\n        <span class=\"c1\"># by satisfying the equality constraints</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_design_var</span><span class=\"p\">(</span><span class=\"s1\">&#39;x&#39;</span><span class=\"p\">,</span> <span class=\"n\">lower</span><span class=\"o\">=</span><span class=\"mf\">0.</span><span class=\"p\">,</span> <span class=\"n\">upper</span><span class=\"o\">=</span><span class=\"mf\">5.</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_design_var</span><span class=\"p\">(</span><span class=\"s1\">&#39;y1&#39;</span><span class=\"p\">,</span> <span class=\"n\">lower</span><span class=\"o\">=</span><span class=\"mf\">0.</span><span class=\"p\">,</span> <span class=\"n\">upper</span><span class=\"o\">=</span><span class=\"mf\">5.</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_design_var</span><span class=\"p\">(</span><span class=\"s1\">&#39;y2&#39;</span><span class=\"p\">,</span> <span class=\"n\">lower</span><span class=\"o\">=</span><span class=\"mf\">0.</span><span class=\"p\">,</span> <span class=\"n\">upper</span><span class=\"o\">=</span><span class=\"mf\">5.</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_design_var</span><span class=\"p\">(</span><span class=\"s1\">&#39;z&#39;</span><span class=\"p\">,</span> <span class=\"n\">lower</span><span class=\"o\">=</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"o\">-</span><span class=\"mf\">5.</span><span class=\"p\">,</span> <span class=\"mf\">0.</span><span class=\"p\">]),</span> <span class=\"n\">upper</span><span class=\"o\">=</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">5.</span><span class=\"p\">,</span> <span class=\"mf\">5.</span><span class=\"p\">]))</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_objective</span><span class=\"p\">(</span><span class=\"s1\">&#39;obj_cmp.obj&#39;</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_constraint</span><span class=\"p\">(</span><span class=\"s1\">&#39;con_cmp1.con1&#39;</span><span class=\"p\">,</span> <span class=\"n\">upper</span><span class=\"o\">=</span><span class=\"mf\">0.</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_constraint</span><span class=\"p\">(</span><span class=\"s1\">&#39;con_cmp2.con2&#39;</span><span class=\"p\">,</span> <span class=\"n\">upper</span><span class=\"o\">=</span><span class=\"mf\">0.</span><span class=\"p\">)</span>\n</pre></div>\n",
      "application/papermill.record/text/latex": "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n\\PY{k}{class}\\PY{+w}{ }\\PY{n+nc}{SellarIDF}\\PY{p}{(}\\PY{n}{om}\\PY{o}{.}\\PY{n}{Group}\\PY{p}{)}\\PY{p}{:}\n\\PY{+w}{    }\\PY{l+s+sd}{\\PYZdq{}\\PYZdq{}\\PYZdq{}}\n\\PY{l+s+sd}{    Individual Design Feasible (IDF) architecture for the Sellar problem.}\n\\PY{l+s+sd}{    \\PYZdq{}\\PYZdq{}\\PYZdq{}}\n    \\PY{k}{def}\\PY{+w}{ }\\PY{n+nf}{setup}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{p}{)}\\PY{p}{:}\n        \\PY{c+c1}{\\PYZsh{} construct the Sellar model with `y1` and `y2` as independent variables}\n\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{set\\PYZus{}input\\PYZus{}defaults}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{x}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{l+m+mf}{5.}\\PY{p}{)}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{set\\PYZus{}input\\PYZus{}defaults}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{y1}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{l+m+mf}{5.}\\PY{p}{)}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{set\\PYZus{}input\\PYZus{}defaults}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{y2}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{l+m+mf}{5.}\\PY{p}{)}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{set\\PYZus{}input\\PYZus{}defaults}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{z}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{np}\\PY{o}{.}\\PY{n}{array}\\PY{p}{(}\\PY{p}{[}\\PY{l+m+mf}{2.}\\PY{p}{,} \\PY{l+m+mf}{0.}\\PY{p}{]}\\PY{p}{)}\\PY{p}{)}\n\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{add\\PYZus{}subsystem}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{d1}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{SellarDis1withDerivatives}\\PY{p}{(}\\PY{p}{)}\\PY{p}{,} \\PY{n}{promotes\\PYZus{}inputs}\\PY{o}{=}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{x}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{z}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{y2}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\\PY{p}{)}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{add\\PYZus{}subsystem}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{d2}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{SellarDis2withDerivatives}\\PY{p}{(}\\PY{p}{)}\\PY{p}{,} \\PY{n}{promotes\\PYZus{}inputs}\\PY{o}{=}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{y1}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{z}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\\PY{p}{)}\n\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{add\\PYZus{}subsystem}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{obj\\PYZus{}cmp}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{om}\\PY{o}{.}\\PY{n}{ExecComp}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{obj = x**2 + z[1] + y1 + exp(\\PYZhy{}y2)}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,}\n                           \\PY{n}{x}\\PY{o}{=}\\PY{l+m+mf}{0.}\\PY{p}{,} \\PY{n}{z}\\PY{o}{=}\\PY{n}{np}\\PY{o}{.}\\PY{n}{array}\\PY{p}{(}\\PY{p}{[}\\PY{l+m+mf}{0.}\\PY{p}{,} \\PY{l+m+mf}{0.}\\PY{p}{]}\\PY{p}{)}\\PY{p}{)}\\PY{p}{,} \\PY{n}{promotes\\PYZus{}inputs}\\PY{o}{=}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{x}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{z}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{y1}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{y2}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\\PY{p}{)}\n\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{add\\PYZus{}subsystem}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{con\\PYZus{}cmp1}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{om}\\PY{o}{.}\\PY{n}{ExecComp}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{con1 = 3.16 \\PYZhy{} y1}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{)}\\PY{p}{,} \\PY{n}{promotes\\PYZus{}inputs}\\PY{o}{=}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{y1}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\\PY{p}{)}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{add\\PYZus{}subsystem}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{con\\PYZus{}cmp2}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{om}\\PY{o}{.}\\PY{n}{ExecComp}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{con2 = y2 \\PYZhy{} 24.0}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{)}\\PY{p}{,} \\PY{n}{promotes\\PYZus{}inputs}\\PY{o}{=}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{y2}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\\PY{p}{)}\n\n        \\PY{c+c1}{\\PYZsh{} rather than create a cycle by connecting d1.y1 to d2.y1 and d2.y2 to d1.y2}\n        \\PY{c+c1}{\\PYZsh{} we will constrain y1 and y2 to be equal for the two disciplines}\n\n        \\PY{n}{equal} \\PY{o}{=} \\PY{n}{om}\\PY{o}{.}\\PY{n}{EQConstraintComp}\\PY{p}{(}\\PY{p}{)}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{add\\PYZus{}subsystem}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{equal}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{equal}\\PY{p}{,} \\PY{n}{promotes\\PYZus{}inputs}\\PY{o}{=}\\PY{p}{[}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{lhs:y1}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{y1}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{)}\\PY{p}{,} \\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{lhs:y2}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{y2}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{)}\\PY{p}{]}\\PY{p}{)}\n\n        \\PY{n}{equal}\\PY{o}{.}\\PY{n}{add\\PYZus{}eq\\PYZus{}output}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{y1}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{add\\PYZus{}constraint}\\PY{o}{=}\\PY{k+kc}{True}\\PY{p}{)}\n        \\PY{n}{equal}\\PY{o}{.}\\PY{n}{add\\PYZus{}eq\\PYZus{}output}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{y2}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{add\\PYZus{}constraint}\\PY{o}{=}\\PY{k+kc}{True}\\PY{p}{)}\n\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{connect}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{d1.y1}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{equal.rhs:y1}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{)}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{connect}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{d2.y2}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{equal.rhs:y2}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{)}\n\n        \\PY{c+c1}{\\PYZsh{} the driver will effectively solve the cycle}\n        \\PY{c+c1}{\\PYZsh{} by satisfying the equality constraints}\n\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{add\\PYZus{}design\\PYZus{}var}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{x}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{lower}\\PY{o}{=}\\PY{l+m+mf}{0.}\\PY{p}{,} \\PY{n}{upper}\\PY{o}{=}\\PY{l+m+mf}{5.}\\PY{p}{)}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{add\\PYZus{}design\\PYZus{}var}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{y1}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{lower}\\PY{o}{=}\\PY{l+m+mf}{0.}\\PY{p}{,} \\PY{n}{upper}\\PY{o}{=}\\PY{l+m+mf}{5.}\\PY{p}{)}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{add\\PYZus{}design\\PYZus{}var}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{y2}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{lower}\\PY{o}{=}\\PY{l+m+mf}{0.}\\PY{p}{,} \\PY{n}{upper}\\PY{o}{=}\\PY{l+m+mf}{5.}\\PY{p}{)}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{add\\PYZus{}design\\PYZus{}var}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{z}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{lower}\\PY{o}{=}\\PY{n}{np}\\PY{o}{.}\\PY{n}{array}\\PY{p}{(}\\PY{p}{[}\\PY{o}{\\PYZhy{}}\\PY{l+m+mf}{5.}\\PY{p}{,} \\PY{l+m+mf}{0.}\\PY{p}{]}\\PY{p}{)}\\PY{p}{,} \\PY{n}{upper}\\PY{o}{=}\\PY{n}{np}\\PY{o}{.}\\PY{n}{array}\\PY{p}{(}\\PY{p}{[}\\PY{l+m+mf}{5.}\\PY{p}{,} \\PY{l+m+mf}{5.}\\PY{p}{]}\\PY{p}{)}\\PY{p}{)}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{add\\PYZus{}objective}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{obj\\PYZus{}cmp.obj}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{)}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{add\\PYZus{}constraint}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{con\\PYZus{}cmp1.con1}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{upper}\\PY{o}{=}\\PY{l+m+mf}{0.}\\PY{p}{)}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{add\\PYZus{}constraint}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{con\\PYZus{}cmp2.con2}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{upper}\\PY{o}{=}\\PY{l+m+mf}{0.}\\PY{p}{)}\n\\end{Verbatim}\n",
      "application/papermill.record/text/plain": "class SellarIDF(om.Group):\n    \"\"\"\n    Individual Design Feasible (IDF) architecture for the Sellar problem.\n    \"\"\"\n    def setup(self):\n        # construct the Sellar model with `y1` and `y2` as independent variables\n\n        self.set_input_defaults('x', 5.)\n        self.set_input_defaults('y1', 5.)\n        self.set_input_defaults('y2', 5.)\n        self.set_input_defaults('z', np.array([2., 0.]))\n\n        self.add_subsystem('d1', SellarDis1withDerivatives(), promotes_inputs=['x', 'z', 'y2'])\n        self.add_subsystem('d2', SellarDis2withDerivatives(), promotes_inputs=['y1', 'z'])\n\n        self.add_subsystem('obj_cmp', om.ExecComp('obj = x**2 + z[1] + y1 + exp(-y2)',\n                           x=0., z=np.array([0., 0.])), promotes_inputs=['x', 'z', 'y1', 'y2'])\n\n        self.add_subsystem('con_cmp1', om.ExecComp('con1 = 3.16 - y1'), promotes_inputs=['y1'])\n        self.add_subsystem('con_cmp2', om.ExecComp('con2 = y2 - 24.0'), promotes_inputs=['y2'])\n\n        # rather than create a cycle by connecting d1.y1 to d2.y1 and d2.y2 to d1.y2\n        # we will constrain y1 and y2 to be equal for the two disciplines\n\n        equal = om.EQConstraintComp()\n        self.add_subsystem('equal', equal, promotes_inputs=[('lhs:y1', 'y1'), ('lhs:y2', 'y2')])\n\n        equal.add_eq_output('y1', add_constraint=True)\n        equal.add_eq_output('y2', add_constraint=True)\n\n        self.connect('d1.y1', 'equal.rhs:y1')\n        self.connect('d2.y2', 'equal.rhs:y2')\n\n        # the driver will effectively solve the cycle\n        # by satisfying the equality constraints\n\n        self.add_design_var('x', lower=0., upper=5.)\n        self.add_design_var('y1', lower=0., upper=5.)\n        self.add_design_var('y2', lower=0., upper=5.)\n        self.add_design_var('z', lower=np.array([-5., 0.]), upper=np.array([5., 5.]))\n        self.add_objective('obj_cmp.obj')\n        self.add_constraint('con_cmp1.con1', upper=0.)\n        self.add_constraint('con_cmp2.con2', upper=0.)"
     },
     "metadata": {
      "scrapbook": {
       "mime_prefix": "application/papermill.record/",
       "name": "code_src14"
      }
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "from openmdao.utils.notebook_utils import get_code\n",
    "from myst_nb import glue\n",
    "glue(\"code_src14\", get_code(\"openmdao.test_suite.components.sellar_feature.SellarIDF\"), display=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c69ab5bb",
   "metadata": {
    "papermill": {
     "duration": 0.001021,
     "end_time": "2026-10-02T14:41:17.255206+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:41:17.254185+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    ":::{dropdown} `SellarIDF` class definition \n",
    "\n",
    "{glue:}`code_src14`\n",
    ":::"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "859d506f",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:41:17.258253Z",
     "iopub.status.busy": "2026-10-02T14:41:17.258080Z",
     "iopub.status.idle": "2026-10-02T14:41:18.510284Z",
     "shell.execute_reply": "2026-10-02T14:41:18.509535Z"
    },
    "papermill": {
     "duration": 1.254845,
     "end_time": "2026-10-02T14:41:18.511137+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:41:17.256292+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1790952078.450863] [runnervm8df0l:6417 :0]        ib_iface.c:1269 UCX  ERROR mana_0: iface 0x563451dfd3c0 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",
      "[1790952078.451108] [runnervm8df0l:6417 :0]      ucp_worker.c:1412 UCX  ERROR uct_iface_open(ud_verbs/mana_0:1) failed: Input/output error\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Optimization terminated successfully    (Exit mode 0)\n",
      "            Current function value: 3.1833939516939638\n",
      "            Iterations: 6\n",
      "            Function evaluations: 6\n",
      "            Gradient evaluations: 6\n",
      "Optimization Complete\n",
      "-----------------------------------\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[runnervm8df0l:06417] pml_ucx.c:313  Error: Failed to create UCP worker\n"
     ]
    }
   ],
   "source": [
    "from openmdao.test_suite.components.sellar_feature import SellarIDF\n",
    "\n",
    "prob = om.Problem(model=SellarIDF())\n",
    "prob.driver = om.ScipyOptimizeDriver(optimizer='SLSQP', disp=True)\n",
    "prob.setup()\n",
    "prob.run_driver();"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "13af1b9b",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:41:18.514789Z",
     "iopub.status.busy": "2026-10-02T14:41:18.514494Z",
     "iopub.status.idle": "2026-10-02T14:41:18.517643Z",
     "shell.execute_reply": "2026-10-02T14:41:18.516968Z"
    },
    "papermill": {
     "duration": 0.005798,
     "end_time": "2026-10-02T14:41:18.518315+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:41:18.512517+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0.]\n"
     ]
    }
   ],
   "source": [
    "print(prob.get_val('x'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "b5bb1a8f",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:41:18.615787Z",
     "iopub.status.busy": "2026-10-02T14:41:18.615500Z",
     "iopub.status.idle": "2026-10-02T14:41:18.620065Z",
     "shell.execute_reply": "2026-10-02T14:41:18.619138Z"
    },
    "papermill": {
     "duration": 0.016307,
     "end_time": "2026-10-02T14:41:18.620589+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:41:18.604282+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[array([3.16]), array([3.15999999])]\n",
      "[array([3.75527776]), array([3.75527776])]\n"
     ]
    }
   ],
   "source": [
    "print([prob.get_val('y1'), prob.get_val('d1.y1')])\n",
    "print([prob.get_val('y2'), prob.get_val('y2')])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "9cdedba4",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:41:18.624570Z",
     "iopub.status.busy": "2026-10-02T14:41:18.624405Z",
     "iopub.status.idle": "2026-10-02T14:41:18.627667Z",
     "shell.execute_reply": "2026-10-02T14:41:18.626880Z"
    },
    "papermill": {
     "duration": 0.005955,
     "end_time": "2026-10-02T14:41:18.628225+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:41:18.622270+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1.97763888 0.        ]\n"
     ]
    }
   ],
   "source": [
    "print(prob.get_val('z'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "6b4cd364",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:41:18.631902Z",
     "iopub.status.busy": "2026-10-02T14:41:18.631706Z",
     "iopub.status.idle": "2026-10-02T14:41:18.635170Z",
     "shell.execute_reply": "2026-10-02T14:41:18.634104Z"
    },
    "papermill": {
     "duration": 0.006129,
     "end_time": "2026-10-02T14:41:18.635743+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:41:18.629614+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[3.18339395]\n"
     ]
    }
   ],
   "source": [
    "print(prob.get_val('obj_cmp.obj'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "9af8bcc0",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:41:18.640015Z",
     "iopub.status.busy": "2026-10-02T14:41:18.639886Z",
     "iopub.status.idle": "2026-10-02T14:41:18.644908Z",
     "shell.execute_reply": "2026-10-02T14:41:18.643991Z"
    },
    "papermill": {
     "duration": 0.00794,
     "end_time": "2026-10-02T14:41:18.645551+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:41:18.637611+00:00",
     "status": "completed"
    },
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "np.float64(3.9076646439568904e-10)"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from openmdao.utils.assert_utils import assert_near_equal\n",
    "\n",
    "assert_near_equal(prob.get_val('x'), 0., 1e-5)\n",
    "\n",
    "assert_near_equal([prob.get_val('y1'), prob.get_val('d1.y1')], [[3.16], [3.16]], 1e-5)\n",
    "assert_near_equal([prob.get_val('y2'), prob.get_val('y2')], [[3.7552778], [3.7552778]], 1e-5)\n",
    "\n",
    "assert_near_equal(prob.get_val('z'), [1.977639, 0.], 1e-5)\n",
    "\n",
    "assert_near_equal(prob.get_val('obj_cmp.obj'), 3.18339395045, 1e-5)"
   ]
  }
 ],
 "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": 5.299876,
   "end_time": "2026-10-02T14:41:19.464396+00:00",
   "environment_variables": {},
   "exception": null,
   "input_path": "/home/runner/work/OpenMDAO/OpenMDAO/openmdao/docs/openmdao_book/features/building_blocks/components/eq_constraint_comp.ipynb",
   "output_path": "/home/runner/work/OpenMDAO/OpenMDAO/openmdao/docs/_executed_book/features/building_blocks/components/eq_constraint_comp.ipynb",
   "parameters": {},
   "start_time": "2026-10-02T14:41:14.164520+00:00",
   "version": "2.7.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}