{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "0689e196",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:46:28.095677Z",
     "iopub.status.busy": "2026-10-02T14:46:28.095487Z",
     "iopub.status.idle": "2026-10-02T14:46:28.099959Z",
     "shell.execute_reply": "2026-10-02T14:46:28.099300Z"
    },
    "papermill": {
     "duration": 0.007204,
     "end_time": "2026-10-02T14:46:28.100508+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:28.093304+00:00",
     "status": "completed"
    },
    "tags": [
     "remove-input",
     "remove-output",
     "active-ipynb"
    ]
   },
   "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": "code",
   "execution_count": 2,
   "id": "fcc6fd0a",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:46:28.104056Z",
     "iopub.status.busy": "2026-10-02T14:46:28.103918Z",
     "iopub.status.idle": "2026-10-02T14:46:28.704197Z",
     "shell.execute_reply": "2026-10-02T14:46:28.703393Z"
    },
    "papermill": {
     "duration": 0.602912,
     "end_time": "2026-10-02T14:46:28.704984+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:28.102072+00:00",
     "status": "completed"
    },
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "from openmdao.utils.assert_utils import assert_near_equal\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "33c01cc9",
   "metadata": {
    "papermill": {
     "duration": 0.09897,
     "end_time": "2026-10-02T14:46:28.805543+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:28.706573+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "# Solver Recording\n",
    "Solver recording is useful when you want to record the iterations within a solver. \n",
    "The recorder can capture the values of states, errors, and residuals as the solver converges."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "fe21ad44",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:46:28.824346Z",
     "iopub.status.busy": "2026-10-02T14:46:28.823982Z",
     "iopub.status.idle": "2026-10-02T14:46:29.565571Z",
     "shell.execute_reply": "2026-10-02T14:46:29.564885Z"
    },
    "papermill": {
     "duration": 0.759368,
     "end_time": "2026-10-02T14:46:29.566426+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:28.807058+00:00",
     "status": "completed"
    },
    "scrolled": true,
    "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;\">excludes</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">[]</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;list&#x27;]</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">Patterns for vars to exclude in recording.                                        (processed post-includes)                                        Paths are relative to solver&#x27;s Group.                                        Uses fnmatch wildcards</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">includes</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">[&#x27;*&#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;\">[&#x27;list&#x27;]</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">Patterns for variables to include in recording.                                        Paths are relative to solver&#x27;s Group.                                        Uses fnmatch wildcards</td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">record_abs_error</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">True</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;\">Set to True to record absolute error at the                                        solver level</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">record_inputs</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">True</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;\">Set to True to record inputs at the solver level</td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">record_outputs</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">True</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;\">Set to True to record outputs at the solver level</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">record_rel_error</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">True</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;\">Set to True to record relative error at the                                        solver level</td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">record_solver_residuals</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;\">Set to True to record residuals at the solver level</td></tr>\n",
       "    </table>\n",
       "</body>\n",
       "</html>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import openmdao.api as om\n",
    "om.show_options_table(\"openmdao.solvers.solver.Solver\", options_dict=\"recording_options\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "21d84a49",
   "metadata": {
    "papermill": {
     "duration": 0.001629,
     "end_time": "2026-10-02T14:46:29.569810+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:29.568181+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "```{note}\n",
    "Note that the `excludes` option takes precedence over the `includes` option.\n",
    "```\n",
    "\n",
    "```{note}\n",
    "The paths given in the `includes` and `excludes` options are relative to the `Group` that the solver is attached to.\n",
    "```\n",
    "\n",
    "```{note}\n",
    "It is currently not possible to record linear solvers.\n",
    "````"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a48b03ac",
   "metadata": {
    "papermill": {
     "duration": 0.001434,
     "end_time": "2026-10-02T14:46:29.572810+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:29.571376+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "## Solver Recording Example"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "dc82b273",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:46:29.577147Z",
     "iopub.status.busy": "2026-10-02T14:46:29.576777Z",
     "iopub.status.idle": "2026-10-02T14:46:30.542170Z",
     "shell.execute_reply": "2026-10-02T14:46:30.541566Z"
    },
    "papermill": {
     "duration": 0.968455,
     "end_time": "2026-10-02T14:46:30.542984+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:29.574529+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\">SellarDerivatives</span><span class=\"p\">(</span><span class=\"n\">om</span><span class=\"o\">.</span><span class=\"n\">Group</span><span class=\"p\">):</span>\n<span class=\"w\">    </span><span class=\"sd\">&quot;&quot;&quot;</span>\n<span class=\"sd\">    Group containing the Sellar MDA. This version uses the disciplines with derivatives.</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_subsystem</span><span class=\"p\">(</span><span class=\"s1\">&#39;d1&#39;</span><span class=\"p\">,</span> <span class=\"n\">SellarDis1withDerivatives</span><span class=\"p\">(),</span> <span class=\"n\">promotes</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"s1\">&#39;x&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;z&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;y1&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;y2&#39;</span><span class=\"p\">])</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_subsystem</span><span class=\"p\">(</span><span class=\"s1\">&#39;d2&#39;</span><span class=\"p\">,</span> <span class=\"n\">SellarDis2withDerivatives</span><span class=\"p\">(),</span> <span class=\"n\">promotes</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"s1\">&#39;z&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;y1&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;y2&#39;</span><span class=\"p\">])</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_subsystem</span><span class=\"p\">(</span><span class=\"s1\">&#39;obj_cmp&#39;</span><span class=\"p\">,</span> <span class=\"n\">om</span><span class=\"o\">.</span><span class=\"n\">ExecComp</span><span class=\"p\">(</span><span class=\"s1\">&#39;obj = x**2 + z[1] + y1 + exp(-y2)&#39;</span><span class=\"p\">,</span> <span class=\"n\">obj</span><span class=\"o\">=</span><span class=\"mf\">0.0</span><span class=\"p\">,</span>\n                                                  <span class=\"n\">x</span><span class=\"o\">=</span><span class=\"mf\">0.0</span><span class=\"p\">,</span> <span class=\"n\">z</span><span class=\"o\">=</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">0.0</span><span class=\"p\">,</span> <span class=\"mf\">0.0</span><span class=\"p\">]),</span> <span class=\"n\">y1</span><span class=\"o\">=</span><span class=\"mf\">0.0</span><span class=\"p\">,</span> <span class=\"n\">y2</span><span class=\"o\">=</span><span class=\"mf\">0.0</span><span class=\"p\">),</span>\n                           <span class=\"n\">promotes</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"s1\">&#39;obj&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;x&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;z&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;y1&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;y2&#39;</span><span class=\"p\">])</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_subsystem</span><span class=\"p\">(</span><span class=\"s1\">&#39;con_cmp1&#39;</span><span class=\"p\">,</span> <span class=\"n\">om</span><span class=\"o\">.</span><span class=\"n\">ExecComp</span><span class=\"p\">(</span><span class=\"s1\">&#39;con1 = 3.16 - y1&#39;</span><span class=\"p\">,</span> <span class=\"n\">con1</span><span class=\"o\">=</span><span class=\"mf\">0.0</span><span class=\"p\">,</span> <span class=\"n\">y1</span><span class=\"o\">=</span><span class=\"mf\">0.0</span><span class=\"p\">),</span>\n                           <span class=\"n\">promotes</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"s1\">&#39;con1&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;y1&#39;</span><span class=\"p\">])</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_subsystem</span><span class=\"p\">(</span><span class=\"s1\">&#39;con_cmp2&#39;</span><span class=\"p\">,</span> <span class=\"n\">om</span><span class=\"o\">.</span><span class=\"n\">ExecComp</span><span class=\"p\">(</span><span class=\"s1\">&#39;con2 = y2 - 24.0&#39;</span><span class=\"p\">,</span> <span class=\"n\">con2</span><span class=\"o\">=</span><span class=\"mf\">0.0</span><span class=\"p\">,</span> <span class=\"n\">y2</span><span class=\"o\">=</span><span class=\"mf\">0.0</span><span class=\"p\">),</span>\n                           <span class=\"n\">promotes</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"s1\">&#39;con2&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;y2&#39;</span><span class=\"p\">])</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">set_input_defaults</span><span class=\"p\">(</span><span class=\"s1\">&#39;x&#39;</span><span class=\"p\">,</span> <span class=\"mf\">1.0</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">set_input_defaults</span><span class=\"p\">(</span><span class=\"s1\">&#39;z&#39;</span><span class=\"p\">,</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">5.0</span><span class=\"p\">,</span> <span class=\"mf\">2.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}{SellarDerivatives}\\PY{p}{(}\\PY{n}{om}\\PY{o}{.}\\PY{n}{Group}\\PY{p}{)}\\PY{p}{:}\n\\PY{+w}{    }\\PY{l+s+sd}{\\PYZdq{}\\PYZdq{}\\PYZdq{}}\n\\PY{l+s+sd}{    Group containing the Sellar MDA. This version uses the disciplines with derivatives.}\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{}subsystem}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{d1}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{SellarDis1withDerivatives}\\PY{p}{(}\\PY{p}{)}\\PY{p}{,} \\PY{n}{promotes}\\PY{o}{=}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{x}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{z}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{y1}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{y2}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\\PY{p}{)}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{add\\PYZus{}subsystem}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{d2}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{SellarDis2withDerivatives}\\PY{p}{(}\\PY{p}{)}\\PY{p}{,} \\PY{n}{promotes}\\PY{o}{=}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{z}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{y1}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{y2}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\\PY{p}{)}\n\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{add\\PYZus{}subsystem}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{obj\\PYZus{}cmp}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{om}\\PY{o}{.}\\PY{n}{ExecComp}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{obj = x**2 + z[1] + y1 + exp(\\PYZhy{}y2)}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{obj}\\PY{o}{=}\\PY{l+m+mf}{0.0}\\PY{p}{,}\n                                                  \\PY{n}{x}\\PY{o}{=}\\PY{l+m+mf}{0.0}\\PY{p}{,} \\PY{n}{z}\\PY{o}{=}\\PY{n}{np}\\PY{o}{.}\\PY{n}{array}\\PY{p}{(}\\PY{p}{[}\\PY{l+m+mf}{0.0}\\PY{p}{,} \\PY{l+m+mf}{0.0}\\PY{p}{]}\\PY{p}{)}\\PY{p}{,} \\PY{n}{y1}\\PY{o}{=}\\PY{l+m+mf}{0.0}\\PY{p}{,} \\PY{n}{y2}\\PY{o}{=}\\PY{l+m+mf}{0.0}\\PY{p}{)}\\PY{p}{,}\n                           \\PY{n}{promotes}\\PY{o}{=}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{obj}\\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{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{z}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{y1}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{y2}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\\PY{p}{)}\n\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{add\\PYZus{}subsystem}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{con\\PYZus{}cmp1}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{om}\\PY{o}{.}\\PY{n}{ExecComp}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{con1 = 3.16 \\PYZhy{} y1}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{con1}\\PY{o}{=}\\PY{l+m+mf}{0.0}\\PY{p}{,} \\PY{n}{y1}\\PY{o}{=}\\PY{l+m+mf}{0.0}\\PY{p}{)}\\PY{p}{,}\n                           \\PY{n}{promotes}\\PY{o}{=}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{con1}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{y1}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\\PY{p}{)}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{add\\PYZus{}subsystem}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{con\\PYZus{}cmp2}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{om}\\PY{o}{.}\\PY{n}{ExecComp}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{con2 = y2 \\PYZhy{} 24.0}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{con2}\\PY{o}{=}\\PY{l+m+mf}{0.0}\\PY{p}{,} \\PY{n}{y2}\\PY{o}{=}\\PY{l+m+mf}{0.0}\\PY{p}{)}\\PY{p}{,}\n                           \\PY{n}{promotes}\\PY{o}{=}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{con2}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{y2}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\\PY{p}{)}\n\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{set\\PYZus{}input\\PYZus{}defaults}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{x}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{l+m+mf}{1.0}\\PY{p}{)}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{set\\PYZus{}input\\PYZus{}defaults}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{z}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{np}\\PY{o}{.}\\PY{n}{array}\\PY{p}{(}\\PY{p}{[}\\PY{l+m+mf}{5.0}\\PY{p}{,} \\PY{l+m+mf}{2.0}\\PY{p}{]}\\PY{p}{)}\\PY{p}{)}\n\\end{Verbatim}\n",
      "application/papermill.record/text/plain": "class SellarDerivatives(om.Group):\n    \"\"\"\n    Group containing the Sellar MDA. This version uses the disciplines with derivatives.\n    \"\"\"\n\n    def setup(self):\n        self.add_subsystem('d1', SellarDis1withDerivatives(), promotes=['x', 'z', 'y1', 'y2'])\n        self.add_subsystem('d2', SellarDis2withDerivatives(), promotes=['z', 'y1', 'y2'])\n\n        self.add_subsystem('obj_cmp', om.ExecComp('obj = x**2 + z[1] + y1 + exp(-y2)', obj=0.0,\n                                                  x=0.0, z=np.array([0.0, 0.0]), y1=0.0, y2=0.0),\n                           promotes=['obj', 'x', 'z', 'y1', 'y2'])\n\n        self.add_subsystem('con_cmp1', om.ExecComp('con1 = 3.16 - y1', con1=0.0, y1=0.0),\n                           promotes=['con1', 'y1'])\n        self.add_subsystem('con_cmp2', om.ExecComp('con2 = y2 - 24.0', con2=0.0, y2=0.0),\n                           promotes=['con2', 'y2'])\n\n        self.set_input_defaults('x', 1.0)\n        self.set_input_defaults('z', np.array([5.0, 2.0]))"
     },
     "metadata": {
      "scrapbook": {
       "mime_prefix": "application/papermill.record/",
       "name": "code_src91"
      }
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "from openmdao.utils.notebook_utils import get_code\n",
    "from myst_nb import glue\n",
    "glue(\"code_src91\", get_code(\"openmdao.test_suite.components.sellar_feature.SellarDerivatives\"), display=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8da9bbea",
   "metadata": {
    "papermill": {
     "duration": 0.001168,
     "end_time": "2026-10-02T14:46:30.569571+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:30.568403+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    ":::{dropdown} `SellarDerivatives` class definition \n",
    "\n",
    "{glue:}`code_src91`\n",
    ":::"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "fab31040",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:46:30.596710Z",
     "iopub.status.busy": "2026-10-02T14:46:30.596497Z",
     "iopub.status.idle": "2026-10-02T14:46:32.405020Z",
     "shell.execute_reply": "2026-10-02T14:46:32.404222Z"
    },
    "papermill": {
     "duration": 1.811515,
     "end_time": "2026-10-02T14:46:32.405620+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:30.594105+00:00",
     "status": "completed"
    },
    "scrolled": true,
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1790952391.834932] [runnervm8df0l:10579:0]        ib_iface.c:1269 UCX  ERROR mana_0: iface 0x555c673a9fb0 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",
      "[1790952391.835190] [runnervm8df0l:10579:0]      ucp_worker.c:1412 UCX  ERROR uct_iface_open(ud_verbs/mana_0:1) failed: Input/output error\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[runnervm8df0l:10579] pml_ucx.c:313  Error: Failed to create UCP worker\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "NL: NLBGS Converged in 7 iterations\n"
     ]
    }
   ],
   "source": [
    "import openmdao.api as om\n",
    "from openmdao.test_suite.components.sellar_feature import SellarDerivatives\n",
    "\n",
    "prob = om.Problem(name='solver_recording', model=SellarDerivatives())\n",
    "prob.setup()\n",
    "\n",
    "recorder = om.SqliteRecorder(\"solver_recording.sql\")\n",
    "\n",
    "solver = prob.model.nonlinear_solver = om.NonlinearBlockGS()\n",
    "solver.add_recorder(recorder)\n",
    "solver.recording_options['record_abs_error'] = True\n",
    "solver.options['use_apply_nonlinear'] = True\n",
    "\n",
    "prob.run_model()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "34be0adb",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:46:32.409333Z",
     "iopub.status.busy": "2026-10-02T14:46:32.409112Z",
     "iopub.status.idle": "2026-10-02T14:46:32.541674Z",
     "shell.execute_reply": "2026-10-02T14:46:32.540981Z"
    },
    "papermill": {
     "duration": 0.135121,
     "end_time": "2026-10-02T14:46:32.542209+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:32.407088+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "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;\">root.nonlinear_solver</th></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:root._solve_nonlinear|0|NonlinearBlockGS|0</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:root._solve_nonlinear|0|NonlinearBlockGS|1</td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:root._solve_nonlinear|0|NonlinearBlockGS|2</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:root._solve_nonlinear|0|NonlinearBlockGS|3</td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:root._solve_nonlinear|0|NonlinearBlockGS|4</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:root._solve_nonlinear|0|NonlinearBlockGS|5</td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:root._solve_nonlinear|0|NonlinearBlockGS|6</td></tr>\n",
       "    </table>\n",
       "</body>\n",
       "</html>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "prob.cleanup()\n",
    "cr = om.CaseReader(prob.get_outputs_dir() / \"solver_recording.sql\")\n",
    "solver_cases = cr.list_cases('root.nonlinear_solver')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "5276ab0a",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:46:32.546206Z",
     "iopub.status.busy": "2026-10-02T14:46:32.546045Z",
     "iopub.status.idle": "2026-10-02T14:46:32.548277Z",
     "shell.execute_reply": "2026-10-02T14:46:32.547848Z"
    },
    "papermill": {
     "duration": 0.004922,
     "end_time": "2026-10-02T14:46:32.548986+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:32.544064+00:00",
     "status": "completed"
    },
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "assert len(solver_cases) == 7"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "b8f777c8",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:46:32.552227Z",
     "iopub.status.busy": "2026-10-02T14:46:32.552077Z",
     "iopub.status.idle": "2026-10-02T14:46:32.556439Z",
     "shell.execute_reply": "2026-10-02T14:46:32.555869Z"
    },
    "papermill": {
     "duration": 0.006721,
     "end_time": "2026-10-02T14:46:32.557015+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:32.550294+00:00",
     "status": "completed"
    },
    "scrolled": true,
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2.2545141061171243\n",
      "0.043663258684468076\n",
      "0.0008635223885384846\n",
      "1.707062189737485e-05\n",
      "3.3746495375908125e-07\n",
      "6.671260877055829e-09\n",
      "1.318802844707534e-10\n"
     ]
    }
   ],
   "source": [
    "for case_id in solver_cases:\n",
    "    print(cr.get_case(case_id).abs_err)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "cc3114c8",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:46:32.560240Z",
     "iopub.status.busy": "2026-10-02T14:46:32.560106Z",
     "iopub.status.idle": "2026-10-02T14:46:32.563875Z",
     "shell.execute_reply": "2026-10-02T14:46:32.563238Z"
    },
    "papermill": {
     "duration": 0.006005,
     "end_time": "2026-10-02T14:46:32.564307+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:32.558302+00:00",
     "status": "completed"
    },
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "np.float64(2.7132782804768756e-09)"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "assert_near_equal(cr.get_case(0).abs_err, 2.2545141, tolerance=1e-8)"
   ]
  }
 ],
 "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.932061,
   "end_time": "2026-10-02T14:46:33.382345+00:00",
   "environment_variables": {},
   "exception": null,
   "input_path": "/home/runner/work/OpenMDAO/OpenMDAO/openmdao/docs/openmdao_book/features/recording/solver_recording.ipynb",
   "output_path": "/home/runner/work/OpenMDAO/OpenMDAO/openmdao/docs/_executed_book/features/recording/solver_recording.ipynb",
   "parameters": {},
   "start_time": "2026-10-02T14:46:27.450284+00:00",
   "version": "2.7.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}