{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "e7953823",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:42:55.141957Z",
     "iopub.status.busy": "2026-10-02T14:42:55.141726Z",
     "iopub.status.idle": "2026-10-02T14:42:55.146750Z",
     "shell.execute_reply": "2026-10-02T14:42:55.146038Z"
    },
    "papermill": {
     "duration": 0.007908,
     "end_time": "2026-10-02T14:42:55.147260+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:42:55.139352+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": "a7081c40",
   "metadata": {
    "papermill": {
     "duration": 0.028044,
     "end_time": "2026-10-02T14:42:55.177200+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:42:55.149156+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "# ScipyKrylov\n",
    "\n",
    "ScipyKrylov is an iterative linear solver that wraps the methods found in `scipy.sparse.linalg`.\n",
    "The default method is \"gmres\", or the Generalized Minimal RESidual method. Support for other\n",
    "`scipy.sparse.linalg` solvers will be added over time. This linear solver is capable of handling any\n",
    "system topology very effectively. It also solves all subsystems below it in the hierarchy, so\n",
    "assigning different solvers to subsystems will have no effect on the solution at this level.\n",
    "\n",
    "This is a serial solver, so it should never be used under MPI; use [PETScKrylov](../../../_srcdocs/packages/solvers.linear/petsc_ksp) instead.\n",
    "\n",
    "Here, we calculate the total derivatives across the Sellar system."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "6d86e32a",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:42:55.182086Z",
     "iopub.status.busy": "2026-10-02T14:42:55.181931Z",
     "iopub.status.idle": "2026-10-02T14:42:57.303207Z",
     "shell.execute_reply": "2026-10-02T14:42:57.302565Z"
    },
    "papermill": {
     "duration": 2.123994,
     "end_time": "2026-10-02T14:42:57.303665+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:42:55.179671+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\">SellarDis1withDerivatives</span><span class=\"p\">(</span><span class=\"n\">SellarDis1</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 -- derivatives version.</span>\n<span class=\"sd\">    &quot;&quot;&quot;</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\"># Analytic Derivs</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">declare_partials</span><span class=\"p\">(</span><span class=\"n\">of</span><span class=\"o\">=</span><span class=\"s1\">&#39;*&#39;</span><span class=\"p\">,</span> <span class=\"n\">wrt</span><span class=\"o\">=</span><span class=\"s1\">&#39;*&#39;</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">compute_partials</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\">partials</span><span class=\"p\">):</span>\n<span class=\"w\">        </span><span class=\"sd\">&quot;&quot;&quot;</span>\n<span class=\"sd\">        Jacobian for Sellar discipline 1.</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"n\">partials</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> <span class=\"o\">=</span> <span class=\"o\">-</span><span class=\"mf\">0.2</span>\n        <span class=\"n\">partials</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> <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\">2.0</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> <span class=\"mf\">1.0</span><span class=\"p\">]])</span>\n        <span class=\"n\">partials</span><span class=\"p\">[</span><span class=\"s1\">&#39;y1&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;x&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"mf\">1.0</span>\n</pre></div>\n",
      "application/papermill.record/text/latex": "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n\\PY{k}{class}\\PY{+w}{ }\\PY{n+nc}{SellarDis1withDerivatives}\\PY{p}{(}\\PY{n}{SellarDis1}\\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{} derivatives version.}\n\\PY{l+s+sd}{    \\PYZdq{}\\PYZdq{}\\PYZdq{}}\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{} Analytic Derivs}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{declare\\PYZus{}partials}\\PY{p}{(}\\PY{n}{of}\\PY{o}{=}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{*}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{wrt}\\PY{o}{=}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{*}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{)}\n\n    \\PY{k}{def}\\PY{+w}{ }\\PY{n+nf}{compute\\PYZus{}partials}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{p}{,} \\PY{n}{inputs}\\PY{p}{,} \\PY{n}{partials}\\PY{p}{)}\\PY{p}{:}\n\\PY{+w}{        }\\PY{l+s+sd}{\\PYZdq{}\\PYZdq{}\\PYZdq{}}\n\\PY{l+s+sd}{        Jacobian for Sellar discipline 1.}\n\\PY{l+s+sd}{        \\PYZdq{}\\PYZdq{}\\PYZdq{}}\n        \\PY{n}{partials}\\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{o}{=} \\PY{o}{\\PYZhy{}}\\PY{l+m+mf}{0.2}\n        \\PY{n}{partials}\\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{o}{=} \\PY{n}{np}\\PY{o}{.}\\PY{n}{array}\\PY{p}{(}\\PY{p}{[}\\PY{p}{[}\\PY{l+m+mf}{2.0} \\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}{]}\\PY{p}{,} \\PY{l+m+mf}{1.0}\\PY{p}{]}\\PY{p}{]}\\PY{p}{)}\n        \\PY{n}{partials}\\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}{x}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]} \\PY{o}{=} \\PY{l+m+mf}{1.0}\n\\end{Verbatim}\n",
      "application/papermill.record/text/plain": "class SellarDis1withDerivatives(SellarDis1):\n    \"\"\"\n    Component containing Discipline 1 -- derivatives version.\n    \"\"\"\n\n    def setup_partials(self):\n        # Analytic Derivs\n        self.declare_partials(of='*', wrt='*')\n\n    def compute_partials(self, inputs, partials):\n        \"\"\"\n        Jacobian for Sellar discipline 1.\n        \"\"\"\n        partials['y1', 'y2'] = -0.2\n        partials['y1', 'z'] = np.array([[2.0 * inputs['z'][0], 1.0]])\n        partials['y1', 'x'] = 1.0"
     },
     "metadata": {
      "scrapbook": {
       "mime_prefix": "application/papermill.record/",
       "name": "code_src41"
      }
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "from openmdao.utils.notebook_utils import get_code\n",
    "from myst_nb import glue\n",
    "glue(\"code_src41\", get_code(\"openmdao.test_suite.components.sellar.SellarDis1withDerivatives\"), display=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "221738ed",
   "metadata": {
    "papermill": {
     "duration": 0.001363,
     "end_time": "2026-10-02T14:42:57.306943+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:42:57.305580+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    ":::{dropdown} `SellarDis1withDerivatives` class definition \n",
    "\n",
    "{glue:}`code_src41`\n",
    ":::"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "8d304107",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:42:57.310300Z",
     "iopub.status.busy": "2026-10-02T14:42:57.310141Z",
     "iopub.status.idle": "2026-10-02T14:42:57.316406Z",
     "shell.execute_reply": "2026-10-02T14:42:57.315661Z"
    },
    "papermill": {
     "duration": 0.008598,
     "end_time": "2026-10-02T14:42:57.316909+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:42:57.308311+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\">SellarDis2withDerivatives</span><span class=\"p\">(</span><span class=\"n\">SellarDis2</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 -- derivatives version.</span>\n<span class=\"sd\">    &quot;&quot;&quot;</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\"># Analytic Derivs</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">declare_partials</span><span class=\"p\">(</span><span class=\"n\">of</span><span class=\"o\">=</span><span class=\"s1\">&#39;*&#39;</span><span class=\"p\">,</span> <span class=\"n\">wrt</span><span class=\"o\">=</span><span class=\"s1\">&#39;*&#39;</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">compute_partials</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\">J</span><span class=\"p\">):</span>\n<span class=\"w\">        </span><span class=\"sd\">&quot;&quot;&quot;</span>\n<span class=\"sd\">        Jacobian for Sellar discipline 2.</span>\n<span class=\"sd\">        &quot;&quot;&quot;</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        <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        <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\">1e-8</span><span class=\"p\">:</span>\n            <span class=\"n\">y1</span> <span class=\"o\">=</span> <span class=\"mf\">1e-8</span>\n\n        <span class=\"n\">J</span><span class=\"p\">[</span><span class=\"s1\">&#39;y2&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;y1&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"mf\">.5</span><span class=\"o\">*</span><span class=\"n\">y1</span><span class=\"o\">**-</span><span class=\"mf\">.5</span>\n        <span class=\"n\">J</span><span class=\"p\">[</span><span class=\"s1\">&#39;y2&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;z&#39;</span><span class=\"p\">]</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\">1.0</span><span class=\"p\">,</span> <span class=\"mf\">1.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}{SellarDis2withDerivatives}\\PY{p}{(}\\PY{n}{SellarDis2}\\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{} derivatives version.}\n\\PY{l+s+sd}{    \\PYZdq{}\\PYZdq{}\\PYZdq{}}\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{} Analytic Derivs}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{declare\\PYZus{}partials}\\PY{p}{(}\\PY{n}{of}\\PY{o}{=}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{*}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{wrt}\\PY{o}{=}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{*}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{)}\n\n    \\PY{k}{def}\\PY{+w}{ }\\PY{n+nf}{compute\\PYZus{}partials}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{p}{,} \\PY{n}{inputs}\\PY{p}{,} \\PY{n}{J}\\PY{p}{)}\\PY{p}{:}\n\\PY{+w}{        }\\PY{l+s+sd}{\\PYZdq{}\\PYZdq{}\\PYZdq{}}\n\\PY{l+s+sd}{        Jacobian for Sellar discipline 2.}\n\\PY{l+s+sd}{        \\PYZdq{}\\PYZdq{}\\PYZdq{}}\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        \\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        \\PY{k}{if} \\PY{n}{y1}\\PY{o}{.}\\PY{n}{real} \\PY{o}{\\PYZlt{}} \\PY{l+m+mf}{1e\\PYZhy{}8}\\PY{p}{:}\n            \\PY{n}{y1} \\PY{o}{=} \\PY{l+m+mf}{1e\\PYZhy{}8}\n\n        \\PY{n}{J}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{y2}\\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{o}{=} \\PY{l+m+mf}{.5}\\PY{o}{*}\\PY{n}{y1}\\PY{o}{*}\\PY{o}{*}\\PY{o}{\\PYZhy{}}\\PY{l+m+mf}{.5}\n        \\PY{n}{J}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{y2}\\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{o}{=} \\PY{n}{np}\\PY{o}{.}\\PY{n}{array}\\PY{p}{(}\\PY{p}{[}\\PY{p}{[}\\PY{l+m+mf}{1.0}\\PY{p}{,} \\PY{l+m+mf}{1.0}\\PY{p}{]}\\PY{p}{]}\\PY{p}{)}\n\\end{Verbatim}\n",
      "application/papermill.record/text/plain": "class SellarDis2withDerivatives(SellarDis2):\n    \"\"\"\n    Component containing Discipline 2 -- derivatives version.\n    \"\"\"\n\n    def setup_partials(self):\n        # Analytic Derivs\n        self.declare_partials(of='*', wrt='*')\n\n    def compute_partials(self, inputs, J):\n        \"\"\"\n        Jacobian for Sellar discipline 2.\n        \"\"\"\n        y1 = inputs['y1']\n        if y1.real < 0.0:\n            y1 *= -1\n        if y1.real < 1e-8:\n            y1 = 1e-8\n\n        J['y2', 'y1'] = .5*y1**-.5\n        J['y2', 'z'] = np.array([[1.0, 1.0]])"
     },
     "metadata": {
      "scrapbook": {
       "mime_prefix": "application/papermill.record/",
       "name": "code_src42"
      }
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "from openmdao.utils.notebook_utils import get_code\n",
    "from myst_nb import glue\n",
    "glue(\"code_src42\", get_code(\"openmdao.test_suite.components.sellar.SellarDis2withDerivatives\"), display=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3db2124f",
   "metadata": {
    "papermill": {
     "duration": 0.004172,
     "end_time": "2026-10-02T14:42:57.354930+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:42:57.350758+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    ":::{dropdown} `SellarDis2withDerivatives` class definition \n",
    "\n",
    "{glue:}`code_src42`\n",
    ":::"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "c4fbbccc",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:42:57.358915Z",
     "iopub.status.busy": "2026-10-02T14:42:57.358771Z",
     "iopub.status.idle": "2026-10-02T14:42:58.608846Z",
     "shell.execute_reply": "2026-10-02T14:42:58.608122Z"
    },
    "papermill": {
     "duration": 1.253084,
     "end_time": "2026-10-02T14:42:58.609450+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:42:57.356366+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1790952178.574886] [runnervm8df0l:7409 :0]        ib_iface.c:1269 UCX  ERROR mana_0: iface 0x55af5250c2b0 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",
      "[1790952178.575132] [runnervm8df0l:7409 :0]      ucp_worker.c:1412 UCX  ERROR uct_iface_open(ud_verbs/mana_0:1) failed: Input/output error\n",
      "NL: NLBGS Converged in 8 iterations\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[runnervm8df0l:07409] pml_ucx.c:313  Error: Failed to create UCP worker\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "import openmdao.api as om\n",
    "from openmdao.test_suite.components.sellar import SellarDis1withDerivatives, SellarDis2withDerivatives\n",
    "\n",
    "prob = om.Problem()\n",
    "model = prob.model\n",
    "\n",
    "model.add_subsystem('d1', SellarDis1withDerivatives(), promotes=['x', 'z', 'y1', 'y2'])\n",
    "model.add_subsystem('d2', SellarDis2withDerivatives(), promotes=['z', 'y1', 'y2'])\n",
    "\n",
    "model.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=['obj', 'x', 'z', 'y1', 'y2'])\n",
    "\n",
    "model.add_subsystem('con_cmp1', om.ExecComp('con1 = 3.16 - y1'), promotes=['con1', 'y1'])\n",
    "model.add_subsystem('con_cmp2', om.ExecComp('con2 = y2 - 24.0'), promotes=['con2', 'y2'])\n",
    "\n",
    "model.nonlinear_solver = om.NonlinearBlockGS()\n",
    "\n",
    "model.linear_solver = om.ScipyKrylov()\n",
    "\n",
    "prob.setup()\n",
    "\n",
    "prob.set_val('x', 1.)\n",
    "prob.set_val('z', np.array([5.0, 2.0]))\n",
    "\n",
    "prob.run_model()\n",
    "\n",
    "wrt = ['z']\n",
    "of = ['obj']\n",
    "\n",
    "J = prob.compute_totals(of=of, wrt=wrt, return_format='flat_dict')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "ef7a2b3d",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:42:58.613856Z",
     "iopub.status.busy": "2026-10-02T14:42:58.613362Z",
     "iopub.status.idle": "2026-10-02T14:42:58.619015Z",
     "shell.execute_reply": "2026-10-02T14:42:58.618380Z"
    },
    "papermill": {
     "duration": 0.008441,
     "end_time": "2026-10-02T14:42:58.619553+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:42:58.611112+00:00",
     "status": "completed"
    },
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "np.float64(2.448121171770101e-09)"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from openmdao.utils.assert_utils import assert_near_equal\n",
    "\n",
    "assert_near_equal(J['obj', 'z'][0][0], 9.61001056, .00001)\n",
    "assert_near_equal(J['obj', 'z'][0][1], 1.78448534, .00001)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "34f31818",
   "metadata": {
    "papermill": {
     "duration": 0.001557,
     "end_time": "2026-10-02T14:42:58.622631+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:42:58.621074+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "## ScipyKrylov Options"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "91e7eafb",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:42:58.626292Z",
     "iopub.status.busy": "2026-10-02T14:42:58.626156Z",
     "iopub.status.idle": "2026-10-02T14:42:58.629251Z",
     "shell.execute_reply": "2026-10-02T14:42:58.628716Z"
    },
    "papermill": {
     "duration": 0.005763,
     "end_time": "2026-10-02T14:42:58.629850+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:42:58.624087+00:00",
     "status": "completed"
    },
    "tags": [
     "remove-input"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "<!DOCTYPE html>\n",
       "<html lang=\"en\">\n",
       "<head>\n",
       "    <style>\n",
       "        h2 {\n",
       "            text-align: center;\n",
       "        }\n",
       "    </style>\n",
       "</head>\n",
       "<body>\n",
       "    <h2></h2>\n",
       "        <table style=\"border: 1px solid #999; border-collapse: collapse;\">\n",
       "        <tr><th style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; background-color: #E9E9E9; text-align: left;\">Option</th><th style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; background-color: #E9E9E9; text-align: left;\">Default</th><th style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; background-color: #E9E9E9; text-align: left;\">Acceptable Values</th><th style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; background-color: #E9E9E9; text-align: left;\">Acceptable Types</th><th style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; background-color: #E9E9E9; text-align: left;\">Description</th></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">assemble_jac</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">False</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">[True, False]</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">[&#x27;bool&#x27;]</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">Activates use of assembled jacobian by this solver.</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">atol</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">1e-12</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">N/A</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">N/A</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">absolute error tolerance</td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">err_on_non_converge</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">False</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">[True, False]</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">[&#x27;bool&#x27;]</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">When True, AnalysisError will be raised if we don&#x27;t converge.</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">iprint</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">1</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">N/A</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">[&#x27;int&#x27;]</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">whether to print output</td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">maxiter</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">1000</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">N/A</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">[&#x27;int&#x27;]</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">maximum number of iterations</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">restart</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">20</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">N/A</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">[&#x27;int&#x27;]</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">Number of iterations between restarts. Larger values increase iteration cost, but may be necessary for convergence. This option applies only to gmres.</td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rhs_checking</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">False</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">N/A</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">[&#x27;bool&#x27;, &#x27;dict&#x27;]</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">If True, check RHS vs. cache and/or zero to avoid some solves.Can also be set to a dict of options for the LinearRHSChecker to allow finer control over it. Allowed options are: (&#x27;check_zero&#x27;, &#x27;rtol&#x27;, &#x27;atol&#x27;, &#x27;max_cache_entries&#x27;, &#x27;collect_stats&#x27;, &#x27;auto&#x27;, &#x27;verbose&#x27;)</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rtol</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">1e-10</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">N/A</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">N/A</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">relative error tolerance</td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">solver</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">gmres</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">[&#x27;gmres&#x27;]</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">N/A</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">function handle for actual solver</td></tr>\n",
       "    </table>\n",
       "</body>\n",
       "</html>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "om.show_options_table(\"openmdao.solvers.linear.scipy_iter_solver.ScipyKrylov\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d667027f",
   "metadata": {
    "papermill": {
     "duration": 0.002224,
     "end_time": "2026-10-02T14:42:58.634543+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:42:58.632319+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "## ScipyKrylov Constructor\n",
    "\n",
    "The call signature for the `ScipyKrylov` constructor is:\n",
    "\n",
    "```{eval-rst}\n",
    "    .. automethod:: openmdao.solvers.linear.scipy_iter_solver.ScipyKrylov.__init__\n",
    "        :noindex:\n",
    "```\n",
    "\n",
    "## ScipyKrylov Option Examples\n",
    "\n",
    "**maxiter**\n",
    "\n",
    "  `maxiter` lets you specify the maximum number of GMRES iterations to apply. The default maximum is 1000, which\n",
    "  is much higher than the other linear solvers because each multiplication by the system Jacobian is considered\n",
    "  to be an iteration. You may have to decrease this value if you have a coupled system that is converging\n",
    "  very slowly. (Of course, in such a case, it may be better to add a preconditioner.)  Alternatively, you\n",
    "  may have to raise it if you have an extremely large number of components in your system (a 1000-component\n",
    "  ring would need 1000 iterations just to make it around once.)\n",
    "\n",
    "  This example shows what happens if you set `maxiter` too low. Since iteration is terminated after only 3 iterations, the solver does not converge and the derivatives will not be correct."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "3adffded",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:42:58.639346Z",
     "iopub.status.busy": "2026-10-02T14:42:58.639220Z",
     "iopub.status.idle": "2026-10-02T14:42:58.649783Z",
     "shell.execute_reply": "2026-10-02T14:42:58.649267Z"
    },
    "papermill": {
     "duration": 0.013702,
     "end_time": "2026-10-02T14:42:58.650369+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:42:58.636667+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "NL: NLBGS Converged in 8 iterations\n",
      "LN: SCIPYSolver 'LN: SCIPY' on system '' failed to converge in 3 iterations.\n"
     ]
    }
   ],
   "source": [
    "from openmdao.test_suite.components.sellar import SellarDis1withDerivatives, SellarDis2withDerivatives\n",
    "\n",
    "prob = om.Problem()\n",
    "model = prob.model\n",
    "\n",
    "model.add_subsystem('d1', SellarDis1withDerivatives(), promotes=['x', 'z', 'y1', 'y2'])\n",
    "model.add_subsystem('d2', SellarDis2withDerivatives(), promotes=['z', 'y1', 'y2'])\n",
    "\n",
    "model.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=['obj', 'x', 'z', 'y1', 'y2'])\n",
    "\n",
    "model.add_subsystem('con_cmp1', om.ExecComp('con1 = 3.16 - y1'), promotes=['con1', 'y1'])\n",
    "model.add_subsystem('con_cmp2', om.ExecComp('con2 = y2 - 24.0'), promotes=['con2', 'y2'])\n",
    "\n",
    "model.nonlinear_solver = om.NonlinearBlockGS()\n",
    "\n",
    "model.linear_solver = om.ScipyKrylov()\n",
    "model.linear_solver.options['maxiter'] = 3\n",
    "\n",
    "prob.setup()\n",
    "\n",
    "prob.set_val('x', 1.)\n",
    "prob.set_val('z', np.array([5.0, 2.0]))\n",
    "\n",
    "prob.run_model()\n",
    "\n",
    "wrt = ['z']\n",
    "of = ['obj']\n",
    "\n",
    "J = prob.compute_totals(of=of, wrt=wrt, return_format='flat_dict')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "8ce8a63a",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:42:58.667723Z",
     "iopub.status.busy": "2026-10-02T14:42:58.667582Z",
     "iopub.status.idle": "2026-10-02T14:42:58.670092Z",
     "shell.execute_reply": "2026-10-02T14:42:58.669441Z"
    },
    "papermill": {
     "duration": 0.018495,
     "end_time": "2026-10-02T14:42:58.670474+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:42:58.651979+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "8.791716342500832\n",
      "1.7766666407127751\n"
     ]
    }
   ],
   "source": [
    "print(J['obj', 'z'][0][0])\n",
    "print(J['obj', 'z'][0][1])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "03d1a643",
   "metadata": {
    "papermill": {
     "duration": 0.001446,
     "end_time": "2026-10-02T14:42:58.673467+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:42:58.672021+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "Depending on your situation, you may want to set the `err_on_non_converge` option to `True`, so that this will raise an AnalysisError."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "80e1e6ed",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:42:58.679296Z",
     "iopub.status.busy": "2026-10-02T14:42:58.679183Z",
     "iopub.status.idle": "2026-10-02T14:42:58.688622Z",
     "shell.execute_reply": "2026-10-02T14:42:58.688009Z"
    },
    "papermill": {
     "duration": 0.014057,
     "end_time": "2026-10-02T14:42:58.689018+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:42:58.674961+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "NL: NLBGS Converged in 8 iterations\n",
      "LN: SCIPYSolver 'LN: SCIPY' on system '' failed to converge in 3 iterations.\n",
      "===\n",
      "Linear Solver failed to converge, derivatives are not valid.\n",
      "===\n"
     ]
    }
   ],
   "source": [
    "from openmdao.test_suite.components.sellar import SellarDis1withDerivatives, SellarDis2withDerivatives\n",
    "from openmdao.api import AnalysisError\n",
    "\n",
    "prob = om.Problem()\n",
    "model = prob.model\n",
    "\n",
    "model.add_subsystem('d1', SellarDis1withDerivatives(), promotes=['x', 'z', 'y1', 'y2'])\n",
    "model.add_subsystem('d2', SellarDis2withDerivatives(), promotes=['z', 'y1', 'y2'])\n",
    "\n",
    "model.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=['obj', 'x', 'z', 'y1', 'y2'])\n",
    "\n",
    "model.add_subsystem('con_cmp1', om.ExecComp('con1 = 3.16 - y1'), promotes=['con1', 'y1'])\n",
    "model.add_subsystem('con_cmp2', om.ExecComp('con2 = y2 - 24.0'), promotes=['con2', 'y2'])\n",
    "\n",
    "model.nonlinear_solver = om.NonlinearBlockGS()\n",
    "\n",
    "model.linear_solver = om.ScipyKrylov()\n",
    "model.linear_solver.options['maxiter'] = 3\n",
    "model.linear_solver.options['err_on_non_converge'] = True\n",
    "\n",
    "prob.setup()\n",
    "\n",
    "prob.set_val('x', 1.)\n",
    "prob.set_val('z', np.array([5.0, 2.0]))\n",
    "\n",
    "prob.run_model()\n",
    "\n",
    "wrt = ['z']\n",
    "of = ['obj']\n",
    "\n",
    "try:\n",
    "    J = prob.compute_totals(of=of, wrt=wrt, return_format='flat_dict')\n",
    "except AnalysisError:\n",
    "    # Special handling for a failure to converge when computing derivatives\n",
    "    print(\"===\\nLinear Solver failed to converge, derivatives are not valid.\\n===\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e4902c19",
   "metadata": {
    "papermill": {
     "duration": 0.001497,
     "end_time": "2026-10-02T14:42:58.692275+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:42:58.690778+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "**atol**\n",
    "\n",
    "  Here, we set the absolute tolerance to a much tighter value (default is 1.0e-12) to show what happens. In\n",
    "  practice, the tolerance serves a dual role in GMRES. In addition to being a termination criteria, the tolerance\n",
    "  also defines what GMRES considers to be tiny. Tiny numbers are replaced by zero when the argument vector is\n",
    "  normalized at the start of each new matrix-vector product. The end result here is that we iterate longer to get\n",
    "  a marginally better answer.\n",
    "\n",
    "  You may need to adjust this setting if you have abnormally large or small values in your global Jacobian."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "480f3f64",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:42:58.711295Z",
     "iopub.status.busy": "2026-10-02T14:42:58.711175Z",
     "iopub.status.idle": "2026-10-02T14:42:58.723491Z",
     "shell.execute_reply": "2026-10-02T14:42:58.722686Z"
    },
    "papermill": {
     "duration": 0.014814,
     "end_time": "2026-10-02T14:42:58.723948+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:42:58.709134+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "NL: NLBGS Converged in 8 iterations\n"
     ]
    }
   ],
   "source": [
    "from openmdao.test_suite.components.sellar import SellarDis1withDerivatives, SellarDis2withDerivatives\n",
    "\n",
    "prob = om.Problem()\n",
    "model = prob.model\n",
    "\n",
    "model.add_subsystem('d1', SellarDis1withDerivatives(), promotes=['x', 'z', 'y1', 'y2'])\n",
    "model.add_subsystem('d2', SellarDis2withDerivatives(), promotes=['z', 'y1', 'y2'])\n",
    "\n",
    "model.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=['obj', 'x', 'z', 'y1', 'y2'])\n",
    "\n",
    "model.add_subsystem('con_cmp1', om.ExecComp('con1 = 3.16 - y1'), promotes=['con1', 'y1'])\n",
    "model.add_subsystem('con_cmp2', om.ExecComp('con2 = y2 - 24.0'), promotes=['con2', 'y2'])\n",
    "\n",
    "model.nonlinear_solver = om.NonlinearBlockGS()\n",
    "\n",
    "model.linear_solver = om.ScipyKrylov()\n",
    "model.linear_solver.options['atol'] = 1.0e-20\n",
    "\n",
    "prob.setup()\n",
    "\n",
    "prob.set_val('x', 1.)\n",
    "prob.set_val('z', np.array([5.0, 2.0]))\n",
    "\n",
    "prob.run_model()\n",
    "\n",
    "wrt = ['z']\n",
    "of = ['obj']\n",
    "\n",
    "J = prob.compute_totals(of=of, wrt=wrt, return_format='flat_dict')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "f7a4ad74",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:42:58.810149Z",
     "iopub.status.busy": "2026-10-02T14:42:58.809866Z",
     "iopub.status.idle": "2026-10-02T14:42:58.813665Z",
     "shell.execute_reply": "2026-10-02T14:42:58.812736Z"
    },
    "papermill": {
     "duration": 0.009196,
     "end_time": "2026-10-02T14:42:58.814243+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:42:58.805047+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "9.610010556989943\n",
      "1.7844853356313637\n"
     ]
    }
   ],
   "source": [
    "print(J['obj', 'z'][0][0])\n",
    "print(J['obj', 'z'][0][1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "f8213d86",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:42:58.892364Z",
     "iopub.status.busy": "2026-10-02T14:42:58.892167Z",
     "iopub.status.idle": "2026-10-02T14:42:58.895600Z",
     "shell.execute_reply": "2026-10-02T14:42:58.895038Z"
    },
    "papermill": {
     "duration": 0.080277,
     "end_time": "2026-10-02T14:42:58.896290+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:42:58.816013+00:00",
     "status": "completed"
    },
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "np.float64(7.642528275347598e-13)"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "assert_near_equal(J['obj', 'z'][0][0], 9.61001055699, .00001)\n",
    "assert_near_equal(J['obj', 'z'][0][1], 1.78448533563, .00001)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "735bdd42",
   "metadata": {
    "papermill": {
     "duration": 0.001638,
     "end_time": "2026-10-02T14:42:58.899795+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:42:58.898157+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "**rtol**\n",
    "\n",
    "  The 'rtol' setting is not supported by SciPy GMRES for versions earlier than SciPy 1.12.0.\n",
    "\n",
    "## Specifying a Preconditioner\n",
    "\n",
    "You can specify a preconditioner to improve the convergence of the iterative linear solution by setting the `precon` attribute. The\n",
    "motivation for using a preconditioner is the observation that iterative methods have better convergence\n",
    "properties if the linear system has a smaller condition number, so the goal of the preconditioner is to\n",
    "improve the condition number in part or all of the Jacobian.\n",
    "\n",
    "Here, we add a Gauss-Seidel preconditioner to a problem that contains two subgroups, each with an implicit component that implements a quadratic\n",
    "equation. These are solved together by a Newton solver at the top.  The goal of the preconditioner here is to solve the smaller linear systems\n",
    "for the quadratic components independently, and use that solution to precondition the full system solution. This is accomplished by setting up\n",
    "the linear solver hierarchy so that the preconditioner is `LinearBlockGS` and the subsytems `sub1` and `sub2` contain a `DirectSolver`.\n",
    "\n",
    "Note that the number of GMRES iterations is lower when using the preconditioner."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "84ac035e",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:42:58.904066Z",
     "iopub.status.busy": "2026-10-02T14:42:58.903925Z",
     "iopub.status.idle": "2026-10-02T14:42:58.913719Z",
     "shell.execute_reply": "2026-10-02T14:42:58.912984Z"
    },
    "papermill": {
     "duration": 0.012759,
     "end_time": "2026-10-02T14:42:58.914176+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:42:58.901417+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\">QuadraticComp</span><span class=\"p\">(</span><span class=\"n\">om</span><span class=\"o\">.</span><span class=\"n\">ImplicitComponent</span><span class=\"p\">):</span>\n<span class=\"w\">    </span><span class=\"sd\">&quot;&quot;&quot;</span>\n<span class=\"sd\">    A Simple Implicit Component representing a Quadratic Equation.</span>\n\n<span class=\"sd\">    R(a, b, c, x) = ax^2 + bx + c</span>\n\n<span class=\"sd\">    Solution via Quadratic Formula:</span>\n<span class=\"sd\">    x = (-b + sqrt(b^2 - 4ac)) / 2a</span>\n<span class=\"sd\">    &quot;&quot;&quot;</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=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_input</span><span class=\"p\">(</span><span class=\"s1\">&#39;a&#39;</span><span class=\"p\">,</span> <span class=\"n\">val</span><span class=\"o\">=</span><span class=\"mf\">1.</span><span class=\"p\">)</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;b&#39;</span><span class=\"p\">,</span> <span class=\"n\">val</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_input</span><span class=\"p\">(</span><span class=\"s1\">&#39;c&#39;</span><span class=\"p\">,</span> <span class=\"n\">val</span><span class=\"o\">=</span><span class=\"mf\">1.</span><span class=\"p\">)</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;x&#39;</span><span class=\"p\">,</span> <span class=\"n\">val</span><span class=\"o\">=</span><span class=\"mf\">1.</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=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">declare_partials</span><span class=\"p\">(</span><span class=\"n\">of</span><span class=\"o\">=</span><span class=\"s1\">&#39;x&#39;</span><span class=\"p\">,</span> <span class=\"n\">wrt</span><span class=\"o\">=</span><span class=\"s1\">&#39;*&#39;</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">apply_nonlinear</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> <span class=\"n\">residuals</span><span class=\"p\">):</span>\n        <span class=\"n\">a</span> <span class=\"o\">=</span> <span class=\"n\">inputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;a&#39;</span><span class=\"p\">]</span>\n        <span class=\"n\">b</span> <span class=\"o\">=</span> <span class=\"n\">inputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;b&#39;</span><span class=\"p\">]</span>\n        <span class=\"n\">c</span> <span class=\"o\">=</span> <span class=\"n\">inputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;c&#39;</span><span class=\"p\">]</span>\n        <span class=\"n\">x</span> <span class=\"o\">=</span> <span class=\"n\">outputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;x&#39;</span><span class=\"p\">]</span>\n        <span class=\"n\">residuals</span><span class=\"p\">[</span><span class=\"s1\">&#39;x&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">a</span> <span class=\"o\">*</span> <span class=\"n\">x</span> <span class=\"o\">**</span> <span class=\"mi\">2</span> <span class=\"o\">+</span> <span class=\"n\">b</span> <span class=\"o\">*</span> <span class=\"n\">x</span> <span class=\"o\">+</span> <span class=\"n\">c</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">solve_nonlinear</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=\"n\">a</span> <span class=\"o\">=</span> <span class=\"n\">inputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;a&#39;</span><span class=\"p\">]</span>\n        <span class=\"n\">b</span> <span class=\"o\">=</span> <span class=\"n\">inputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;b&#39;</span><span class=\"p\">]</span>\n        <span class=\"n\">c</span> <span class=\"o\">=</span> <span class=\"n\">inputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;c&#39;</span><span class=\"p\">]</span>\n        <span class=\"n\">outputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;x&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"p\">(</span><span class=\"o\">-</span><span class=\"n\">b</span> <span class=\"o\">+</span> <span class=\"p\">(</span><span class=\"n\">b</span> <span class=\"o\">**</span> <span class=\"mi\">2</span> <span class=\"o\">-</span> <span class=\"mi\">4</span> <span class=\"o\">*</span> <span class=\"n\">a</span> <span class=\"o\">*</span> <span class=\"n\">c</span><span class=\"p\">)</span> <span class=\"o\">**</span> <span class=\"mf\">0.5</span><span class=\"p\">)</span> <span class=\"o\">/</span> <span class=\"p\">(</span><span class=\"mi\">2</span> <span class=\"o\">*</span> <span class=\"n\">a</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">linearize</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> <span class=\"n\">partials</span><span class=\"p\">):</span>\n        <span class=\"n\">a</span> <span class=\"o\">=</span> <span class=\"n\">inputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;a&#39;</span><span class=\"p\">]</span>\n        <span class=\"n\">b</span> <span class=\"o\">=</span> <span class=\"n\">inputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;b&#39;</span><span class=\"p\">]</span>\n        <span class=\"n\">x</span> <span class=\"o\">=</span> <span class=\"n\">outputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;x&#39;</span><span class=\"p\">]</span>\n\n        <span class=\"n\">partials</span><span class=\"p\">[</span><span class=\"s1\">&#39;x&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;a&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">x</span> <span class=\"o\">**</span> <span class=\"mi\">2</span>\n        <span class=\"n\">partials</span><span class=\"p\">[</span><span class=\"s1\">&#39;x&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;b&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">x</span>\n        <span class=\"n\">partials</span><span class=\"p\">[</span><span class=\"s1\">&#39;x&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;c&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"mf\">1.0</span>\n        <span class=\"n\">partials</span><span class=\"p\">[</span><span class=\"s1\">&#39;x&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;x&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"mi\">2</span> <span class=\"o\">*</span> <span class=\"n\">a</span> <span class=\"o\">*</span> <span class=\"n\">x</span> <span class=\"o\">+</span> <span class=\"n\">b</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">inv_jac</span> <span class=\"o\">=</span> <span class=\"mf\">1.0</span> <span class=\"o\">/</span> <span class=\"p\">(</span><span class=\"mi\">2</span> <span class=\"o\">*</span> <span class=\"n\">a</span> <span class=\"o\">*</span> <span class=\"n\">x</span> <span class=\"o\">+</span> <span class=\"n\">b</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}{QuadraticComp}\\PY{p}{(}\\PY{n}{om}\\PY{o}{.}\\PY{n}{ImplicitComponent}\\PY{p}{)}\\PY{p}{:}\n\\PY{+w}{    }\\PY{l+s+sd}{\\PYZdq{}\\PYZdq{}\\PYZdq{}}\n\\PY{l+s+sd}{    A Simple Implicit Component representing a Quadratic Equation.}\n\n\\PY{l+s+sd}{    R(a, b, c, x) = ax\\PYZca{}2 + bx + c}\n\n\\PY{l+s+sd}{    Solution via Quadratic Formula:}\n\\PY{l+s+sd}{    x = (\\PYZhy{}b + sqrt(b\\PYZca{}2 \\PYZhy{} 4ac)) / 2a}\n\\PY{l+s+sd}{    \\PYZdq{}\\PYZdq{}\\PYZdq{}}\n\n    \\PY{k}{def}\\PY{+w}{ }\\PY{n+nf}{setup}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{p}{)}\\PY{p}{:}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{add\\PYZus{}input}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{a}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{val}\\PY{o}{=}\\PY{l+m+mf}{1.}\\PY{p}{)}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{add\\PYZus{}input}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{b}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{val}\\PY{o}{=}\\PY{l+m+mf}{5.}\\PY{p}{)}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{add\\PYZus{}input}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{c}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{val}\\PY{o}{=}\\PY{l+m+mf}{1.}\\PY{p}{)}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{add\\PYZus{}output}\\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}{1.}\\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{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{declare\\PYZus{}partials}\\PY{p}{(}\\PY{n}{of}\\PY{o}{=}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{x}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{wrt}\\PY{o}{=}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{*}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{)}\n\n    \\PY{k}{def}\\PY{+w}{ }\\PY{n+nf}{apply\\PYZus{}nonlinear}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{p}{,} \\PY{n}{inputs}\\PY{p}{,} \\PY{n}{outputs}\\PY{p}{,} \\PY{n}{residuals}\\PY{p}{)}\\PY{p}{:}\n        \\PY{n}{a} \\PY{o}{=} \\PY{n}{inputs}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{a}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\n        \\PY{n}{b} \\PY{o}{=} \\PY{n}{inputs}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{b}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\n        \\PY{n}{c} \\PY{o}{=} \\PY{n}{inputs}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{c}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\n        \\PY{n}{x} \\PY{o}{=} \\PY{n}{outputs}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{x}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\n        \\PY{n}{residuals}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{x}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]} \\PY{o}{=} \\PY{n}{a} \\PY{o}{*} \\PY{n}{x} \\PY{o}{*}\\PY{o}{*} \\PY{l+m+mi}{2} \\PY{o}{+} \\PY{n}{b} \\PY{o}{*} \\PY{n}{x} \\PY{o}{+} \\PY{n}{c}\n\n    \\PY{k}{def}\\PY{+w}{ }\\PY{n+nf}{solve\\PYZus{}nonlinear}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{p}{,} \\PY{n}{inputs}\\PY{p}{,} \\PY{n}{outputs}\\PY{p}{)}\\PY{p}{:}\n        \\PY{n}{a} \\PY{o}{=} \\PY{n}{inputs}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{a}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\n        \\PY{n}{b} \\PY{o}{=} \\PY{n}{inputs}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{b}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\n        \\PY{n}{c} \\PY{o}{=} \\PY{n}{inputs}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{c}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\n        \\PY{n}{outputs}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{x}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]} \\PY{o}{=} \\PY{p}{(}\\PY{o}{\\PYZhy{}}\\PY{n}{b} \\PY{o}{+} \\PY{p}{(}\\PY{n}{b} \\PY{o}{*}\\PY{o}{*} \\PY{l+m+mi}{2} \\PY{o}{\\PYZhy{}} \\PY{l+m+mi}{4} \\PY{o}{*} \\PY{n}{a} \\PY{o}{*} \\PY{n}{c}\\PY{p}{)} \\PY{o}{*}\\PY{o}{*} \\PY{l+m+mf}{0.5}\\PY{p}{)} \\PY{o}{/} \\PY{p}{(}\\PY{l+m+mi}{2} \\PY{o}{*} \\PY{n}{a}\\PY{p}{)}\n\n    \\PY{k}{def}\\PY{+w}{ }\\PY{n+nf}{linearize}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{p}{,} \\PY{n}{inputs}\\PY{p}{,} \\PY{n}{outputs}\\PY{p}{,} \\PY{n}{partials}\\PY{p}{)}\\PY{p}{:}\n        \\PY{n}{a} \\PY{o}{=} \\PY{n}{inputs}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{a}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\n        \\PY{n}{b} \\PY{o}{=} \\PY{n}{inputs}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{b}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\n        \\PY{n}{x} \\PY{o}{=} \\PY{n}{outputs}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{x}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\n\n        \\PY{n}{partials}\\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}{a}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]} \\PY{o}{=} \\PY{n}{x} \\PY{o}{*}\\PY{o}{*} \\PY{l+m+mi}{2}\n        \\PY{n}{partials}\\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}{b}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]} \\PY{o}{=} \\PY{n}{x}\n        \\PY{n}{partials}\\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}{c}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]} \\PY{o}{=} \\PY{l+m+mf}{1.0}\n        \\PY{n}{partials}\\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}{x}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]} \\PY{o}{=} \\PY{l+m+mi}{2} \\PY{o}{*} \\PY{n}{a} \\PY{o}{*} \\PY{n}{x} \\PY{o}{+} \\PY{n}{b}\n\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{inv\\PYZus{}jac} \\PY{o}{=} \\PY{l+m+mf}{1.0} \\PY{o}{/} \\PY{p}{(}\\PY{l+m+mi}{2} \\PY{o}{*} \\PY{n}{a} \\PY{o}{*} \\PY{n}{x} \\PY{o}{+} \\PY{n}{b}\\PY{p}{)}\n\\end{Verbatim}\n",
      "application/papermill.record/text/plain": "class QuadraticComp(om.ImplicitComponent):\n    \"\"\"\n    A Simple Implicit Component representing a Quadratic Equation.\n\n    R(a, b, c, x) = ax^2 + bx + c\n\n    Solution via Quadratic Formula:\n    x = (-b + sqrt(b^2 - 4ac)) / 2a\n    \"\"\"\n\n    def setup(self):\n        self.add_input('a', val=1.)\n        self.add_input('b', val=5.)\n        self.add_input('c', val=1.)\n        self.add_output('x', val=1.)\n\n    def setup_partials(self):\n        self.declare_partials(of='x', wrt='*')\n\n    def apply_nonlinear(self, inputs, outputs, residuals):\n        a = inputs['a']\n        b = inputs['b']\n        c = inputs['c']\n        x = outputs['x']\n        residuals['x'] = a * x ** 2 + b * x + c\n\n    def solve_nonlinear(self, inputs, outputs):\n        a = inputs['a']\n        b = inputs['b']\n        c = inputs['c']\n        outputs['x'] = (-b + (b ** 2 - 4 * a * c) ** 0.5) / (2 * a)\n\n    def linearize(self, inputs, outputs, partials):\n        a = inputs['a']\n        b = inputs['b']\n        x = outputs['x']\n\n        partials['x', 'a'] = x ** 2\n        partials['x', 'b'] = x\n        partials['x', 'c'] = 1.0\n        partials['x', 'x'] = 2 * a * x + b\n\n        self.inv_jac = 1.0 / (2 * a * x + b)"
     },
     "metadata": {
      "scrapbook": {
       "mime_prefix": "application/papermill.record/",
       "name": "code_src43"
      }
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "from openmdao.utils.notebook_utils import get_code\n",
    "from myst_nb import glue\n",
    "glue(\"code_src43\", get_code(\"openmdao.test_suite.components.quad_implicit.QuadraticComp\"), display=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bdc7e59a",
   "metadata": {
    "papermill": {
     "duration": 0.001759,
     "end_time": "2026-10-02T14:42:58.919388+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:42:58.917629+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    ":::{dropdown} `QuadraticComp` class definition \n",
    "\n",
    "{glue:}`code_src43`\n",
    ":::"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "864ab892",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:42:59.503778Z",
     "iopub.status.busy": "2026-10-02T14:42:59.503515Z",
     "iopub.status.idle": "2026-10-02T14:42:59.642887Z",
     "shell.execute_reply": "2026-10-02T14:42:59.642308Z"
    },
    "papermill": {
     "duration": 0.722361,
     "end_time": "2026-10-02T14:42:59.643596+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:42:58.921235+00:00",
     "status": "completed"
    },
    "scrolled": true,
    "tags": [
     "output_scroll"
    ]
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "NL: Newton 0 ; 13.9900036 1\n",
      "|  | precon: LNBGS 0 ; 13.9900036 1\n",
      "|  | precon: LNBGS 1 ; 6.99 0.499642474\n",
      "|  | precon: LNBGS 2 ; 1.42653061e-05 1.01967852e-06\n",
      "|  | precon: LNBGS 3 ; 2.91136004e-11 2.0810288e-12\n",
      "|  | precon:LN: LNBGS Converged\n",
      "|  | precon: LNBGS 0 ; 2.91136004e-11 1\n",
      "|  | precon:LN: LNBGS Converged\n",
      "|  | precon: LNBGS 0 ; 0 0\n",
      "|  | precon:LN: LNBGS Converged\n",
      "|  LN: SCIPY 0 ; 0 0\n",
      "NL: Newton 1 ; 2.87790104e-06 2.05711244e-07\n",
      "|  | precon: LNBGS 0 ; 13.9899975 1\n",
      "|  | precon: LNBGS 1 ; 6.98999999 0.499642691\n",
      "|  | precon: LNBGS 2 ; 1.42769417e-05 1.02051067e-06\n",
      "|  | precon: LNBGS 3 ; 2.91603814e-11 2.0843736e-12\n",
      "|  | precon:LN: LNBGS Converged\n",
      "|  | precon: LNBGS 0 ; 27.979997 1\n",
      "|  | precon: LNBGS 1 ; 13.98 0.499642655\n",
      "|  | precon: LNBGS 2 ; 2.85538835e-05 1.0205106e-06\n",
      "|  | precon: LNBGS 3 ; 5.83204596e-11 2.08436261e-12\n",
      "|  | precon:LN: LNBGS Converged\n",
      "|  | precon: LNBGS 0 ; 0 0\n",
      "|  | precon:LN: LNBGS Converged\n",
      "|  LN: SCIPY 0 ; 0 0\n",
      "|  LN: SCIPYSolver 'LN: SCIPY' on system '' failed to converge in 1 iterations.\n",
      "NL: Newton 2 ; 5.84040093e-11 4.17469581e-12\n",
      "NL: Newton Converged\n"
     ]
    }
   ],
   "source": [
    "from openmdao.test_suite.components.quad_implicit import QuadraticComp\n",
    "\n",
    "prob = om.Problem()\n",
    "model = prob.model\n",
    "\n",
    "sub1 = model.add_subsystem('sub1', om.Group())\n",
    "sub1.add_subsystem('q1', QuadraticComp())\n",
    "sub1.add_subsystem('z1', om.ExecComp('y = -6.0 + .01 * x'))\n",
    "sub2 = model.add_subsystem('sub2', om.Group())\n",
    "sub2.add_subsystem('q2', QuadraticComp())\n",
    "sub2.add_subsystem('z2', om.ExecComp('y = -6.0 + .01 * x'))\n",
    "\n",
    "model.connect('sub1.q1.x', 'sub1.z1.x')\n",
    "model.connect('sub1.z1.y', 'sub2.q2.c')\n",
    "model.connect('sub2.q2.x', 'sub2.z2.x')\n",
    "model.connect('sub2.z2.y', 'sub1.q1.c')\n",
    "\n",
    "model.nonlinear_solver = om.NewtonSolver(solve_subsystems=False)\n",
    "model.linear_solver = om.ScipyKrylov()\n",
    "\n",
    "prob.setup()\n",
    "\n",
    "model.sub1.linear_solver = om.DirectSolver()\n",
    "model.sub2.linear_solver = om.DirectSolver()\n",
    "\n",
    "model.linear_solver.precon = om.LinearBlockGS()\n",
    "\n",
    "prob.set_solver_print(level=2)\n",
    "prob.run_model()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "2e5693e5",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:42:59.648519Z",
     "iopub.status.busy": "2026-10-02T14:42:59.648367Z",
     "iopub.status.idle": "2026-10-02T14:42:59.651389Z",
     "shell.execute_reply": "2026-10-02T14:42:59.650781Z"
    },
    "papermill": {
     "duration": 0.006207,
     "end_time": "2026-10-02T14:42:59.651929+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:42:59.645722+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0.99857318]\n",
      "[0.99857318]\n"
     ]
    }
   ],
   "source": [
    "print(prob.get_val('sub1.q1.x'))\n",
    "print(prob.get_val('sub2.q2.x'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "541add3a",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:42:59.656436Z",
     "iopub.status.busy": "2026-10-02T14:42:59.656300Z",
     "iopub.status.idle": "2026-10-02T14:42:59.659579Z",
     "shell.execute_reply": "2026-10-02T14:42:59.658939Z"
    },
    "papermill": {
     "duration": 0.006215,
     "end_time": "2026-10-02T14:42:59.660016+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:42:59.653801+00:00",
     "status": "completed"
    },
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "np.float64(3.946652227376968e-09)"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "assert_near_equal(prob.get_val('sub1.q1.x'), 0.99857318, .0001)\n",
    "assert_near_equal(prob.get_val('sub2.q2.x'), 0.99857318, .0001)"
   ]
  }
 ],
 "metadata": {
  "celltoolbar": "Tags",
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "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.803102,
   "end_time": "2026-10-02T14:43:00.277434+00:00",
   "environment_variables": {},
   "exception": null,
   "input_path": "/home/runner/work/OpenMDAO/OpenMDAO/openmdao/docs/openmdao_book/features/building_blocks/solvers/scipy_iter_solver.ipynb",
   "output_path": "/home/runner/work/OpenMDAO/OpenMDAO/openmdao/docs/_executed_book/features/building_blocks/solvers/scipy_iter_solver.ipynb",
   "parameters": {},
   "start_time": "2026-10-02T14:42:54.474332+00:00",
   "version": "2.7.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}