{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "9026c83d",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:40:32.240637Z",
     "iopub.status.busy": "2026-10-02T14:40:32.240427Z",
     "iopub.status.idle": "2026-10-02T14:40:32.245007Z",
     "shell.execute_reply": "2026-10-02T14:40:32.244570Z"
    },
    "papermill": {
     "duration": 0.007539,
     "end_time": "2026-10-02T14:40:32.245886+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:40:32.238347+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": "146958f5",
   "metadata": {
    "papermill": {
     "duration": 0.000868,
     "end_time": "2026-10-02T14:40:32.249775+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:40:32.248907+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "# Visualizing The Structure of Your Model\n",
    "\n",
    "OpenMDAO models can have deep hierarchies of groups and components, with many connections between them.\n",
    "Often times, it is helpful to visualize the model structure. OpenMDAO provides a model visualization tool\n",
    "that is accessible via the [openmdao](om-command-n2) command line tool.\n",
    "\n",
    "For example, if you had built the Sellar problem with a missing connection, and you figured out that there\n",
    "was a missing connection by running [check setup](../command_line/check_setup),\n",
    "then you might want to take a closer look at the model to help figure out what's going on."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "9c184ff1",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:40:32.252416Z",
     "iopub.status.busy": "2026-10-02T14:40:32.252211Z",
     "iopub.status.idle": "2026-10-02T14:40:34.484670Z",
     "shell.execute_reply": "2026-10-02T14:40:34.484184Z"
    },
    "papermill": {
     "duration": 2.234649,
     "end_time": "2026-10-02T14:40:34.485271+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:40:32.250622+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\">SellarDis1</span><span class=\"p\">(</span><span class=\"n\">om</span><span class=\"o\">.</span><span class=\"n\">ExplicitComponent</span><span class=\"p\">):</span>\n<span class=\"w\">    </span><span class=\"sd\">&quot;&quot;&quot;</span>\n<span class=\"sd\">    Component containing Discipline 1 -- no derivatives version.</span>\n<span class=\"sd\">    &quot;&quot;&quot;</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">units</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"n\">scaling</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n        <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"fm\">__init__</span><span class=\"p\">()</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">execution_count</span> <span class=\"o\">=</span> <span class=\"mi\">0</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_units</span> <span class=\"o\">=</span> <span class=\"n\">units</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_do_scaling</span> <span class=\"o\">=</span> <span class=\"n\">scaling</span>\n\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\n        <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_units</span><span class=\"p\">:</span>\n            <span class=\"n\">units</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;ft&#39;</span>\n        <span class=\"k\">else</span><span class=\"p\">:</span>\n            <span class=\"n\">units</span> <span class=\"o\">=</span> <span class=\"kc\">None</span>\n\n        <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_do_scaling</span><span class=\"p\">:</span>\n            <span class=\"n\">ref</span> <span class=\"o\">=</span> <span class=\"mf\">.1</span>\n        <span class=\"k\">else</span><span class=\"p\">:</span>\n            <span class=\"n\">ref</span> <span class=\"o\">=</span> <span class=\"mf\">1.</span>\n\n        <span class=\"c1\"># Global Design Variable</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_input</span><span class=\"p\">(</span><span class=\"s1\">&#39;z&#39;</span><span class=\"p\">,</span> <span class=\"n\">val</span><span class=\"o\">=</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">zeros</span><span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">),</span> <span class=\"n\">units</span><span class=\"o\">=</span><span class=\"n\">units</span><span class=\"p\">)</span>\n\n        <span class=\"c1\"># Local Design Variable</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_input</span><span class=\"p\">(</span><span class=\"s1\">&#39;x&#39;</span><span class=\"p\">,</span> <span class=\"n\">val</span><span class=\"o\">=</span><span class=\"mf\">0.</span><span class=\"p\">,</span> <span class=\"n\">units</span><span class=\"o\">=</span><span class=\"n\">units</span><span class=\"p\">)</span>\n\n        <span class=\"c1\"># Coupling parameter</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_input</span><span class=\"p\">(</span><span class=\"s1\">&#39;y2&#39;</span><span class=\"p\">,</span> <span class=\"n\">val</span><span class=\"o\">=</span><span class=\"mf\">1.0</span><span class=\"p\">,</span> <span class=\"n\">units</span><span class=\"o\">=</span><span class=\"n\">units</span><span class=\"p\">)</span>\n\n        <span class=\"c1\"># Coupling output</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_output</span><span class=\"p\">(</span><span class=\"s1\">&#39;y1&#39;</span><span class=\"p\">,</span> <span class=\"n\">val</span><span class=\"o\">=</span><span class=\"mf\">1.0</span><span class=\"p\">,</span> <span class=\"n\">lower</span><span class=\"o\">=</span><span class=\"mf\">0.1</span><span class=\"p\">,</span> <span class=\"n\">upper</span><span class=\"o\">=</span><span class=\"mf\">1000.</span><span class=\"p\">,</span> <span class=\"n\">units</span><span class=\"o\">=</span><span class=\"n\">units</span><span class=\"p\">,</span> <span class=\"n\">ref</span><span class=\"o\">=</span><span class=\"n\">ref</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">setup_partials</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"c1\"># Finite difference everything</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">declare_partials</span><span class=\"p\">(</span><span class=\"s1\">&#39;*&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;*&#39;</span><span class=\"p\">,</span> <span class=\"n\">method</span><span class=\"o\">=</span><span class=\"s1\">&#39;fd&#39;</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">compute</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">inputs</span><span class=\"p\">,</span> <span class=\"n\">outputs</span><span class=\"p\">):</span>\n<span class=\"w\">        </span><span class=\"sd\">&quot;&quot;&quot;</span>\n<span class=\"sd\">        Evaluates the equation</span>\n<span class=\"sd\">        y1 = z1**2 + z2 + x1 - 0.2*y2</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n\n        <span class=\"n\">z1</span> <span class=\"o\">=</span> <span class=\"n\">inputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;z&#39;</span><span class=\"p\">][</span><span class=\"mi\">0</span><span class=\"p\">]</span>\n        <span class=\"n\">z2</span> <span class=\"o\">=</span> <span class=\"n\">inputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;z&#39;</span><span class=\"p\">][</span><span class=\"mi\">1</span><span class=\"p\">]</span>\n        <span class=\"n\">x1</span> <span class=\"o\">=</span> <span class=\"n\">inputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;x&#39;</span><span class=\"p\">]</span>\n        <span class=\"n\">y2</span> <span class=\"o\">=</span> <span class=\"n\">inputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;y2&#39;</span><span class=\"p\">]</span>\n\n        <span class=\"n\">outputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;y1&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">z1</span><span class=\"o\">**</span><span class=\"mi\">2</span> <span class=\"o\">+</span> <span class=\"n\">z2</span> <span class=\"o\">+</span> <span class=\"n\">x1</span> <span class=\"o\">-</span> <span class=\"mf\">0.2</span><span class=\"o\">*</span><span class=\"n\">y2</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">execution_count</span> <span class=\"o\">+=</span> <span class=\"mi\">1</span>\n</pre></div>\n",
      "application/papermill.record/text/latex": "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n\\PY{k}{class}\\PY{+w}{ }\\PY{n+nc}{SellarDis1}\\PY{p}{(}\\PY{n}{om}\\PY{o}{.}\\PY{n}{ExplicitComponent}\\PY{p}{)}\\PY{p}{:}\n\\PY{+w}{    }\\PY{l+s+sd}{\\PYZdq{}\\PYZdq{}\\PYZdq{}}\n\\PY{l+s+sd}{    Component containing Discipline 1 \\PYZhy{}\\PYZhy{} no derivatives version.}\n\\PY{l+s+sd}{    \\PYZdq{}\\PYZdq{}\\PYZdq{}}\n\n    \\PY{k}{def}\\PY{+w}{ }\\PY{n+nf+fm}{\\PYZus{}\\PYZus{}init\\PYZus{}\\PYZus{}}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{p}{,} \\PY{n}{units}\\PY{o}{=}\\PY{k+kc}{None}\\PY{p}{,} \\PY{n}{scaling}\\PY{o}{=}\\PY{k+kc}{None}\\PY{p}{)}\\PY{p}{:}\n        \\PY{n+nb}{super}\\PY{p}{(}\\PY{p}{)}\\PY{o}{.}\\PY{n+nf+fm}{\\PYZus{}\\PYZus{}init\\PYZus{}\\PYZus{}}\\PY{p}{(}\\PY{p}{)}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{execution\\PYZus{}count} \\PY{o}{=} \\PY{l+m+mi}{0}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{\\PYZus{}units} \\PY{o}{=} \\PY{n}{units}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{\\PYZus{}do\\PYZus{}scaling} \\PY{o}{=} \\PY{n}{scaling}\n\n    \\PY{k}{def}\\PY{+w}{ }\\PY{n+nf}{setup}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{p}{)}\\PY{p}{:}\n\n        \\PY{k}{if} \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{\\PYZus{}units}\\PY{p}{:}\n            \\PY{n}{units} \\PY{o}{=} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{ft}\\PY{l+s+s1}{\\PYZsq{}}\n        \\PY{k}{else}\\PY{p}{:}\n            \\PY{n}{units} \\PY{o}{=} \\PY{k+kc}{None}\n\n        \\PY{k}{if} \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{\\PYZus{}do\\PYZus{}scaling}\\PY{p}{:}\n            \\PY{n}{ref} \\PY{o}{=} \\PY{l+m+mf}{.1}\n        \\PY{k}{else}\\PY{p}{:}\n            \\PY{n}{ref} \\PY{o}{=} \\PY{l+m+mf}{1.}\n\n        \\PY{c+c1}{\\PYZsh{} Global Design Variable}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{add\\PYZus{}input}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{z}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{val}\\PY{o}{=}\\PY{n}{np}\\PY{o}{.}\\PY{n}{zeros}\\PY{p}{(}\\PY{l+m+mi}{2}\\PY{p}{)}\\PY{p}{,} \\PY{n}{units}\\PY{o}{=}\\PY{n}{units}\\PY{p}{)}\n\n        \\PY{c+c1}{\\PYZsh{} Local Design Variable}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{add\\PYZus{}input}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{x}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{val}\\PY{o}{=}\\PY{l+m+mf}{0.}\\PY{p}{,} \\PY{n}{units}\\PY{o}{=}\\PY{n}{units}\\PY{p}{)}\n\n        \\PY{c+c1}{\\PYZsh{} Coupling parameter}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{add\\PYZus{}input}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{y2}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{val}\\PY{o}{=}\\PY{l+m+mf}{1.0}\\PY{p}{,} \\PY{n}{units}\\PY{o}{=}\\PY{n}{units}\\PY{p}{)}\n\n        \\PY{c+c1}{\\PYZsh{} Coupling output}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{add\\PYZus{}output}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{y1}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{val}\\PY{o}{=}\\PY{l+m+mf}{1.0}\\PY{p}{,} \\PY{n}{lower}\\PY{o}{=}\\PY{l+m+mf}{0.1}\\PY{p}{,} \\PY{n}{upper}\\PY{o}{=}\\PY{l+m+mf}{1000.}\\PY{p}{,} \\PY{n}{units}\\PY{o}{=}\\PY{n}{units}\\PY{p}{,} \\PY{n}{ref}\\PY{o}{=}\\PY{n}{ref}\\PY{p}{)}\n\n    \\PY{k}{def}\\PY{+w}{ }\\PY{n+nf}{setup\\PYZus{}partials}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{p}{)}\\PY{p}{:}\n        \\PY{c+c1}{\\PYZsh{} Finite difference everything}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{declare\\PYZus{}partials}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{*}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{*}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{method}\\PY{o}{=}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{fd}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{)}\n\n    \\PY{k}{def}\\PY{+w}{ }\\PY{n+nf}{compute}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{p}{,} \\PY{n}{inputs}\\PY{p}{,} \\PY{n}{outputs}\\PY{p}{)}\\PY{p}{:}\n\\PY{+w}{        }\\PY{l+s+sd}{\\PYZdq{}\\PYZdq{}\\PYZdq{}}\n\\PY{l+s+sd}{        Evaluates the equation}\n\\PY{l+s+sd}{        y1 = z1**2 + z2 + x1 \\PYZhy{} 0.2*y2}\n\\PY{l+s+sd}{        \\PYZdq{}\\PYZdq{}\\PYZdq{}}\n\n        \\PY{n}{z1} \\PY{o}{=} \\PY{n}{inputs}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{z}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\\PY{p}{[}\\PY{l+m+mi}{0}\\PY{p}{]}\n        \\PY{n}{z2} \\PY{o}{=} \\PY{n}{inputs}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{z}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\\PY{p}{[}\\PY{l+m+mi}{1}\\PY{p}{]}\n        \\PY{n}{x1} \\PY{o}{=} \\PY{n}{inputs}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{x}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\n        \\PY{n}{y2} \\PY{o}{=} \\PY{n}{inputs}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{y2}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\n\n        \\PY{n}{outputs}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{y1}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]} \\PY{o}{=} \\PY{n}{z1}\\PY{o}{*}\\PY{o}{*}\\PY{l+m+mi}{2} \\PY{o}{+} \\PY{n}{z2} \\PY{o}{+} \\PY{n}{x1} \\PY{o}{\\PYZhy{}} \\PY{l+m+mf}{0.2}\\PY{o}{*}\\PY{n}{y2}\n\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{execution\\PYZus{}count} \\PY{o}{+}\\PY{o}{=} \\PY{l+m+mi}{1}\n\\end{Verbatim}\n",
      "application/papermill.record/text/plain": "class SellarDis1(om.ExplicitComponent):\n    \"\"\"\n    Component containing Discipline 1 -- no derivatives version.\n    \"\"\"\n\n    def __init__(self, units=None, scaling=None):\n        super().__init__()\n        self.execution_count = 0\n        self._units = units\n        self._do_scaling = scaling\n\n    def setup(self):\n\n        if self._units:\n            units = 'ft'\n        else:\n            units = None\n\n        if self._do_scaling:\n            ref = .1\n        else:\n            ref = 1.\n\n        # Global Design Variable\n        self.add_input('z', val=np.zeros(2), units=units)\n\n        # Local Design Variable\n        self.add_input('x', val=0., units=units)\n\n        # Coupling parameter\n        self.add_input('y2', val=1.0, units=units)\n\n        # Coupling output\n        self.add_output('y1', val=1.0, lower=0.1, upper=1000., units=units, ref=ref)\n\n    def setup_partials(self):\n        # Finite difference everything\n        self.declare_partials('*', '*', method='fd')\n\n    def compute(self, inputs, outputs):\n        \"\"\"\n        Evaluates the equation\n        y1 = z1**2 + z2 + x1 - 0.2*y2\n        \"\"\"\n\n        z1 = inputs['z'][0]\n        z2 = inputs['z'][1]\n        x1 = inputs['x']\n        y2 = inputs['y2']\n\n        outputs['y1'] = z1**2 + z2 + x1 - 0.2*y2\n\n        self.execution_count += 1"
     },
     "metadata": {
      "scrapbook": {
       "mime_prefix": "application/papermill.record/",
       "name": "code_src3"
      }
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "from openmdao.utils.notebook_utils import get_code\n",
    "from myst_nb import glue\n",
    "glue(\"code_src3\", get_code(\"openmdao.test_suite.components.sellar.SellarDis1\"), display=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d44ab4ff",
   "metadata": {
    "papermill": {
     "duration": 0.001398,
     "end_time": "2026-10-02T14:40:34.488257+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:40:34.486859+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    ":::{dropdown} `SellarDis1` class definition \n",
    "\n",
    "{glue:}`code_src3`\n",
    ":::"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "9d035f9b",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:40:34.491681Z",
     "iopub.status.busy": "2026-10-02T14:40:34.491532Z",
     "iopub.status.idle": "2026-10-02T14:40:34.499505Z",
     "shell.execute_reply": "2026-10-02T14:40:34.498726Z"
    },
    "papermill": {
     "duration": 0.010686,
     "end_time": "2026-10-02T14:40:34.500275+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:40:34.489589+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\">SellarDis2</span><span class=\"p\">(</span><span class=\"n\">om</span><span class=\"o\">.</span><span class=\"n\">ExplicitComponent</span><span class=\"p\">):</span>\n<span class=\"w\">    </span><span class=\"sd\">&quot;&quot;&quot;</span>\n<span class=\"sd\">    Component containing Discipline 2 -- no derivatives version.</span>\n<span class=\"sd\">    &quot;&quot;&quot;</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">units</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"n\">scaling</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n        <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"fm\">__init__</span><span class=\"p\">()</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">execution_count</span> <span class=\"o\">=</span> <span class=\"mi\">0</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_units</span> <span class=\"o\">=</span> <span class=\"n\">units</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_do_scaling</span> <span class=\"o\">=</span> <span class=\"n\">scaling</span>\n\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=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_units</span><span class=\"p\">:</span>\n            <span class=\"n\">units</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;inch&#39;</span>\n        <span class=\"k\">else</span><span class=\"p\">:</span>\n            <span class=\"n\">units</span> <span class=\"o\">=</span> <span class=\"kc\">None</span>\n\n        <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_do_scaling</span><span class=\"p\">:</span>\n            <span class=\"n\">ref</span> <span class=\"o\">=</span> <span class=\"mf\">.18</span>\n        <span class=\"k\">else</span><span class=\"p\">:</span>\n            <span class=\"n\">ref</span> <span class=\"o\">=</span> <span class=\"mf\">1.</span>\n\n        <span class=\"c1\"># Global Design Variable</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_input</span><span class=\"p\">(</span><span class=\"s1\">&#39;z&#39;</span><span class=\"p\">,</span> <span class=\"n\">val</span><span class=\"o\">=</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">zeros</span><span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">),</span> <span class=\"n\">units</span><span class=\"o\">=</span><span class=\"n\">units</span><span class=\"p\">)</span>\n\n        <span class=\"c1\"># Coupling parameter</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_input</span><span class=\"p\">(</span><span class=\"s1\">&#39;y1&#39;</span><span class=\"p\">,</span> <span class=\"n\">val</span><span class=\"o\">=</span><span class=\"mf\">1.0</span><span class=\"p\">,</span> <span class=\"n\">units</span><span class=\"o\">=</span><span class=\"n\">units</span><span class=\"p\">)</span>\n\n        <span class=\"c1\"># Coupling output</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_output</span><span class=\"p\">(</span><span class=\"s1\">&#39;y2&#39;</span><span class=\"p\">,</span> <span class=\"n\">val</span><span class=\"o\">=</span><span class=\"mf\">1.0</span><span class=\"p\">,</span> <span class=\"n\">lower</span><span class=\"o\">=</span><span class=\"mf\">0.1</span><span class=\"p\">,</span> <span class=\"n\">upper</span><span class=\"o\">=</span><span class=\"mf\">1000.</span><span class=\"p\">,</span> <span class=\"n\">units</span><span class=\"o\">=</span><span class=\"n\">units</span><span class=\"p\">,</span> <span class=\"n\">ref</span><span class=\"o\">=</span><span class=\"n\">ref</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">setup_partials</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"c1\"># Finite difference everything</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">declare_partials</span><span class=\"p\">(</span><span class=\"s1\">&#39;*&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;*&#39;</span><span class=\"p\">,</span> <span class=\"n\">method</span><span class=\"o\">=</span><span class=\"s1\">&#39;fd&#39;</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">compute</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">inputs</span><span class=\"p\">,</span> <span class=\"n\">outputs</span><span class=\"p\">):</span>\n<span class=\"w\">        </span><span class=\"sd\">&quot;&quot;&quot;</span>\n<span class=\"sd\">        Evaluates the equation</span>\n<span class=\"sd\">        y2 = y1**(.5) + z1 + z2</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n\n        <span class=\"n\">z1</span> <span class=\"o\">=</span> <span class=\"n\">inputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;z&#39;</span><span class=\"p\">][</span><span class=\"mi\">0</span><span class=\"p\">]</span>\n        <span class=\"n\">z2</span> <span class=\"o\">=</span> <span class=\"n\">inputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;z&#39;</span><span class=\"p\">][</span><span class=\"mi\">1</span><span class=\"p\">]</span>\n        <span class=\"n\">y1</span> <span class=\"o\">=</span> <span class=\"n\">inputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;y1&#39;</span><span class=\"p\">]</span>\n\n        <span class=\"c1\"># Note: this may cause some issues. However, y1 is constrained to be</span>\n        <span class=\"c1\"># above 3.16, so lets just let it converge, and the optimizer will</span>\n        <span class=\"c1\"># throw it out</span>\n        <span class=\"k\">if</span> <span class=\"n\">y1</span><span class=\"o\">.</span><span class=\"n\">real</span> <span class=\"o\">&lt;</span> <span class=\"mf\">0.0</span><span class=\"p\">:</span>\n            <span class=\"n\">y1</span> <span class=\"o\">*=</span> <span class=\"o\">-</span><span class=\"mi\">1</span>\n\n        <span class=\"n\">outputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;y2&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">y1</span><span class=\"o\">**</span><span class=\"mf\">.5</span> <span class=\"o\">+</span> <span class=\"n\">z1</span> <span class=\"o\">+</span> <span class=\"n\">z2</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">execution_count</span> <span class=\"o\">+=</span> <span class=\"mi\">1</span>\n</pre></div>\n",
      "application/papermill.record/text/latex": "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n\\PY{k}{class}\\PY{+w}{ }\\PY{n+nc}{SellarDis2}\\PY{p}{(}\\PY{n}{om}\\PY{o}{.}\\PY{n}{ExplicitComponent}\\PY{p}{)}\\PY{p}{:}\n\\PY{+w}{    }\\PY{l+s+sd}{\\PYZdq{}\\PYZdq{}\\PYZdq{}}\n\\PY{l+s+sd}{    Component containing Discipline 2 \\PYZhy{}\\PYZhy{} no derivatives version.}\n\\PY{l+s+sd}{    \\PYZdq{}\\PYZdq{}\\PYZdq{}}\n\n    \\PY{k}{def}\\PY{+w}{ }\\PY{n+nf+fm}{\\PYZus{}\\PYZus{}init\\PYZus{}\\PYZus{}}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{p}{,} \\PY{n}{units}\\PY{o}{=}\\PY{k+kc}{None}\\PY{p}{,} \\PY{n}{scaling}\\PY{o}{=}\\PY{k+kc}{None}\\PY{p}{)}\\PY{p}{:}\n        \\PY{n+nb}{super}\\PY{p}{(}\\PY{p}{)}\\PY{o}{.}\\PY{n+nf+fm}{\\PYZus{}\\PYZus{}init\\PYZus{}\\PYZus{}}\\PY{p}{(}\\PY{p}{)}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{execution\\PYZus{}count} \\PY{o}{=} \\PY{l+m+mi}{0}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{\\PYZus{}units} \\PY{o}{=} \\PY{n}{units}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{\\PYZus{}do\\PYZus{}scaling} \\PY{o}{=} \\PY{n}{scaling}\n\n    \\PY{k}{def}\\PY{+w}{ }\\PY{n+nf}{setup}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{p}{)}\\PY{p}{:}\n        \\PY{k}{if} \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{\\PYZus{}units}\\PY{p}{:}\n            \\PY{n}{units} \\PY{o}{=} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{inch}\\PY{l+s+s1}{\\PYZsq{}}\n        \\PY{k}{else}\\PY{p}{:}\n            \\PY{n}{units} \\PY{o}{=} \\PY{k+kc}{None}\n\n        \\PY{k}{if} \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{\\PYZus{}do\\PYZus{}scaling}\\PY{p}{:}\n            \\PY{n}{ref} \\PY{o}{=} \\PY{l+m+mf}{.18}\n        \\PY{k}{else}\\PY{p}{:}\n            \\PY{n}{ref} \\PY{o}{=} \\PY{l+m+mf}{1.}\n\n        \\PY{c+c1}{\\PYZsh{} Global Design Variable}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{add\\PYZus{}input}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{z}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{val}\\PY{o}{=}\\PY{n}{np}\\PY{o}{.}\\PY{n}{zeros}\\PY{p}{(}\\PY{l+m+mi}{2}\\PY{p}{)}\\PY{p}{,} \\PY{n}{units}\\PY{o}{=}\\PY{n}{units}\\PY{p}{)}\n\n        \\PY{c+c1}{\\PYZsh{} Coupling parameter}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{add\\PYZus{}input}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{y1}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{val}\\PY{o}{=}\\PY{l+m+mf}{1.0}\\PY{p}{,} \\PY{n}{units}\\PY{o}{=}\\PY{n}{units}\\PY{p}{)}\n\n        \\PY{c+c1}{\\PYZsh{} Coupling output}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{add\\PYZus{}output}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{y2}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{val}\\PY{o}{=}\\PY{l+m+mf}{1.0}\\PY{p}{,} \\PY{n}{lower}\\PY{o}{=}\\PY{l+m+mf}{0.1}\\PY{p}{,} \\PY{n}{upper}\\PY{o}{=}\\PY{l+m+mf}{1000.}\\PY{p}{,} \\PY{n}{units}\\PY{o}{=}\\PY{n}{units}\\PY{p}{,} \\PY{n}{ref}\\PY{o}{=}\\PY{n}{ref}\\PY{p}{)}\n\n    \\PY{k}{def}\\PY{+w}{ }\\PY{n+nf}{setup\\PYZus{}partials}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{p}{)}\\PY{p}{:}\n        \\PY{c+c1}{\\PYZsh{} Finite difference everything}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{declare\\PYZus{}partials}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{*}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{*}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{method}\\PY{o}{=}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{fd}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{)}\n\n    \\PY{k}{def}\\PY{+w}{ }\\PY{n+nf}{compute}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{p}{,} \\PY{n}{inputs}\\PY{p}{,} \\PY{n}{outputs}\\PY{p}{)}\\PY{p}{:}\n\\PY{+w}{        }\\PY{l+s+sd}{\\PYZdq{}\\PYZdq{}\\PYZdq{}}\n\\PY{l+s+sd}{        Evaluates the equation}\n\\PY{l+s+sd}{        y2 = y1**(.5) + z1 + z2}\n\\PY{l+s+sd}{        \\PYZdq{}\\PYZdq{}\\PYZdq{}}\n\n        \\PY{n}{z1} \\PY{o}{=} \\PY{n}{inputs}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{z}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\\PY{p}{[}\\PY{l+m+mi}{0}\\PY{p}{]}\n        \\PY{n}{z2} \\PY{o}{=} \\PY{n}{inputs}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{z}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\\PY{p}{[}\\PY{l+m+mi}{1}\\PY{p}{]}\n        \\PY{n}{y1} \\PY{o}{=} \\PY{n}{inputs}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{y1}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\n\n        \\PY{c+c1}{\\PYZsh{} Note: this may cause some issues. However, y1 is constrained to be}\n        \\PY{c+c1}{\\PYZsh{} above 3.16, so lets just let it converge, and the optimizer will}\n        \\PY{c+c1}{\\PYZsh{} throw it out}\n        \\PY{k}{if} \\PY{n}{y1}\\PY{o}{.}\\PY{n}{real} \\PY{o}{\\PYZlt{}} \\PY{l+m+mf}{0.0}\\PY{p}{:}\n            \\PY{n}{y1} \\PY{o}{*}\\PY{o}{=} \\PY{o}{\\PYZhy{}}\\PY{l+m+mi}{1}\n\n        \\PY{n}{outputs}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{y2}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]} \\PY{o}{=} \\PY{n}{y1}\\PY{o}{*}\\PY{o}{*}\\PY{l+m+mf}{.5} \\PY{o}{+} \\PY{n}{z1} \\PY{o}{+} \\PY{n}{z2}\n\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{execution\\PYZus{}count} \\PY{o}{+}\\PY{o}{=} \\PY{l+m+mi}{1}\n\\end{Verbatim}\n",
      "application/papermill.record/text/plain": "class SellarDis2(om.ExplicitComponent):\n    \"\"\"\n    Component containing Discipline 2 -- no derivatives version.\n    \"\"\"\n\n    def __init__(self, units=None, scaling=None):\n        super().__init__()\n        self.execution_count = 0\n        self._units = units\n        self._do_scaling = scaling\n\n    def setup(self):\n        if self._units:\n            units = 'inch'\n        else:\n            units = None\n\n        if self._do_scaling:\n            ref = .18\n        else:\n            ref = 1.\n\n        # Global Design Variable\n        self.add_input('z', val=np.zeros(2), units=units)\n\n        # Coupling parameter\n        self.add_input('y1', val=1.0, units=units)\n\n        # Coupling output\n        self.add_output('y2', val=1.0, lower=0.1, upper=1000., units=units, ref=ref)\n\n    def setup_partials(self):\n        # Finite difference everything\n        self.declare_partials('*', '*', method='fd')\n\n    def compute(self, inputs, outputs):\n        \"\"\"\n        Evaluates the equation\n        y2 = y1**(.5) + z1 + z2\n        \"\"\"\n\n        z1 = inputs['z'][0]\n        z2 = inputs['z'][1]\n        y1 = inputs['y1']\n\n        # Note: this may cause some issues. However, y1 is constrained to be\n        # above 3.16, so lets just let it converge, and the optimizer will\n        # throw it out\n        if y1.real < 0.0:\n            y1 *= -1\n\n        outputs['y2'] = y1**.5 + z1 + z2\n\n        self.execution_count += 1"
     },
     "metadata": {
      "scrapbook": {
       "mime_prefix": "application/papermill.record/",
       "name": "code_src4"
      }
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "from openmdao.utils.notebook_utils import get_code\n",
    "from myst_nb import glue\n",
    "glue(\"code_src4\", get_code(\"openmdao.test_suite.components.sellar.SellarDis2\"), display=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "84e9bd79",
   "metadata": {
    "papermill": {
     "duration": 0.001426,
     "end_time": "2026-10-02T14:40:34.503267+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:40:34.501841+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    ":::{dropdown} `SellarDis2` class definition \n",
    "\n",
    "{glue:}`code_src4`\n",
    ":::"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "0d88ce01",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:40:34.654235Z",
     "iopub.status.busy": "2026-10-02T14:40:34.653938Z",
     "iopub.status.idle": "2026-10-02T14:40:35.934604Z",
     "shell.execute_reply": "2026-10-02T14:40:35.934087Z"
    },
    "papermill": {
     "duration": 1.4305,
     "end_time": "2026-10-02T14:40:35.935228+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:40:34.504728+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1790952035.870822] [runnervm8df0l:5926 :0]        ib_iface.c:1269 UCX  ERROR mana_0: iface 0x5585bc321410 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",
      "[1790952035.871068] [runnervm8df0l:5926 :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.1870337508710627\n",
      "            Iterations: 9\n",
      "            Function evaluations: 10\n",
      "            Gradient evaluations: 9\n",
      "Optimization Complete\n",
      "-----------------------------------\n",
      "minimum found at\n",
      "0.0\n",
      "[1.83303028e+00 1.06402336e-12]\n",
      "minumum objective\n",
      "3.1870337508710627\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[runnervm8df0l:05926] 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/core/driver.py:829: DriverWarning:The following design variable initial conditions are out of their specified bounds:\n",
      "  z\n",
      "    val: [-1. -1.]\n",
      "    lower: 0.0\n",
      "    upper: 10.0\n",
      "Set the initial value of the design variable to a valid value or set the driver option['invalid_desvar_behavior'] to 'ignore'.\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "import openmdao.api as om\n",
    "\n",
    "from openmdao.test_suite.components.sellar import SellarDis1, SellarDis2\n",
    "\n",
    "\n",
    "class SellarMDAConnect(om.Group):\n",
    "\n",
    "    def setup(self):\n",
    "        cycle = self.add_subsystem('cycle', om.Group(), promotes_inputs=['x', 'z'])\n",
    "        cycle.add_subsystem('d1', SellarDis1(), promotes_inputs=['x', 'z'])\n",
    "        cycle.add_subsystem('d2', SellarDis2(), promotes_inputs=['z'])\n",
    "        cycle.connect('d1.y1', 'd2.y1')\n",
    "\n",
    "        ######################################\n",
    "        # This is a \"forgotten\" connection!!\n",
    "        ######################################\n",
    "        #cycle.connect('d2.y2', 'd1.y2')\n",
    "\n",
    "        self.set_input_defaults('x', 1.0)\n",
    "        self.set_input_defaults('z', np.array([5.0, 2.0]))\n",
    "\n",
    "        # Nonlinear Block Gauss Seidel is a gradient free solver\n",
    "        cycle.nonlinear_solver = om.NonlinearBlockGS()\n",
    "\n",
    "        self.add_subsystem('obj_cmp', om.ExecComp('obj = x**2 + z[1] + y1 + exp(-y2)',\n",
    "                                                  z=np.array([0.0, 0.0]), x=0.0),\n",
    "                           promotes_inputs=['x', 'z'])\n",
    "\n",
    "        self.add_subsystem('con_cmp1', om.ExecComp('con1 = 3.16 - y1'))\n",
    "        self.add_subsystem('con_cmp2', om.ExecComp('con2 = y2 - 24.0'))\n",
    "\n",
    "        self.connect('cycle.d1.y1', ['obj_cmp.y1', 'con_cmp1.y1'])\n",
    "        self.connect('cycle.d2.y2', ['obj_cmp.y2', 'con_cmp2.y2'])\n",
    "\n",
    "\n",
    "prob = om.Problem()\n",
    "\n",
    "prob.model = SellarMDAConnect()\n",
    "\n",
    "prob.driver = om.ScipyOptimizeDriver()\n",
    "prob.driver.options['optimizer'] = 'SLSQP'\n",
    "prob.driver.options['tol'] = 1e-8\n",
    "\n",
    "prob.set_solver_print(level=0)\n",
    "\n",
    "prob.model.add_design_var('x', lower=0, upper=10)\n",
    "prob.model.add_design_var('z', lower=0, upper=10)\n",
    "prob.model.add_objective('obj_cmp.obj')\n",
    "prob.model.add_constraint('con_cmp1.con1', upper=0)\n",
    "prob.model.add_constraint('con_cmp2.con2', upper=0)\n",
    "\n",
    "prob.setup()\n",
    "\n",
    "prob.set_val('x', 2.0)\n",
    "prob.set_val('z', [-1., -1.])\n",
    "\n",
    "prob.run_driver()\n",
    "print('minimum found at')\n",
    "print(prob.get_val('x')[0])\n",
    "print(prob.get_val('z'))\n",
    "print('minumum objective')\n",
    "print(prob.get_val('obj_cmp.obj')[0])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1f2966e4",
   "metadata": {
    "papermill": {
     "duration": 0.001543,
     "end_time": "2026-10-02T14:40:35.938600+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:40:35.937057+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "You can generate a visualization of the model in $N^2$ form with the following command:\n",
    "```\n",
    "openmdao n2 sellar.py\n",
    "```\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "5756590d",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:40:35.943168Z",
     "iopub.status.busy": "2026-10-02T14:40:35.942882Z",
     "iopub.status.idle": "2026-10-02T14:40:36.004415Z",
     "shell.execute_reply": "2026-10-02T14:40:36.003924Z"
    },
    "papermill": {
     "duration": 0.064307,
     "end_time": "2026-10-02T14:40:36.004916+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:40:35.940609+00:00",
     "status": "completed"
    },
    "tags": [
     "remove-input"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "        <iframe\n",
       "            width=\"100%\"\n",
       "            height=\"700\"\n",
       "            src=\"n2.html\"\n",
       "            frameborder=\"0\"\n",
       "            allowfullscreen\n",
       "            \n",
       "        ></iframe>\n",
       "        "
      ],
      "text/plain": [
       "<IPython.lib.display.IFrame at 0x7f0abcd2f8c0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "om.n2(prob, show_browser=False, embeddable=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0d6d7f02",
   "metadata": {
    "papermill": {
     "duration": 0.001619,
     "end_time": "2026-10-02T14:40:36.008291+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:40:36.006672+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "This diagram is a version of a design-structure matrix, with the model hierarchy displayed on the left side.\n",
    "On the diagonal is each input and output of each of the components. Off-diagonal blocks indicate data connections.\n",
    "Feed-forward connections are shown in the upper triangle, and feed-back connections (the kind that cause cycles) are shown in the lower triangle.\n",
    "If you hover over any of the blocks on the diagonal, the incoming and outgoing connections are highlighted with arrows.\n",
    "\n",
    "The unconnected input mentioned above, `cycle.d1.y2`, is highlighted in red to immediately draw attention to a possible problem.\n",
    "You can also see that it's a member of the cycle group (in this case, that was obvious by its name, but with variable promotion that will not always be the case).\n",
    "Furthermore, you can see that the variable you would want to connect `cycle.d1.y1` to, `cycle.d2.y2`, is in the same group.\n",
    "The lack of cycles in the model is made visually evident by the lack of any connections in the lower triangle of the diagram.\n",
    "\n",
    "Collapse groups down by right-clicking on them, and zoom in and out of different parts of the hierarchy by left-clicking.\n",
    "These controls help show that the $N^2$ diagram is a powerful tool for letting you inspect and understand large, complex models.\n",
    "\n",
    "The right side of the diagram shows the solver hierarchy. Initially, it shows the linear solvers but by clicking on\n",
    "the `Toggle Solver Names` button in the toolbar, the names of the nonlinear solvers can be displayed."
   ]
  }
 ],
 "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"
  },
  "papermill": {
   "default_parameters": {},
   "duration": 5.254272,
   "end_time": "2026-10-02T14:40:36.827324+00:00",
   "environment_variables": {},
   "exception": null,
   "input_path": "/home/runner/work/OpenMDAO/OpenMDAO/openmdao/docs/openmdao_book/basic_user_guide/command_line/make_n2.ipynb",
   "output_path": "/home/runner/work/OpenMDAO/OpenMDAO/openmdao/docs/_executed_book/basic_user_guide/command_line/make_n2.ipynb",
   "parameters": {},
   "start_time": "2026-10-02T14:40:31.573052+00:00",
   "version": "2.7.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}