{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "61353e86",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:45:56.885719Z",
     "iopub.status.busy": "2026-10-02T14:45:56.884837Z",
     "iopub.status.idle": "2026-10-02T14:45:56.895387Z",
     "shell.execute_reply": "2026-10-02T14:45:56.894484Z"
    },
    "papermill": {
     "duration": 0.017849,
     "end_time": "2026-10-02T14:45:56.896018+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:45:56.878169+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": "markdown",
   "id": "ba1fed0b",
   "metadata": {
    "papermill": {
     "duration": 0.004043,
     "end_time": "2026-10-02T14:45:56.904901+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:45:56.900858+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "# Case Reader\n",
    "\n",
    "The `CaseReader` object is provided to read case recordings, regardless of which case recorder was used. \n",
    "\n",
    "Currently, OpenMDAO only implements `SqliteCaseRecorder`, therefore all the examples will make use of this recorder. Other types of case recorders are expected to be supported in the future."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fe2178dc",
   "metadata": {
    "papermill": {
     "duration": 0.001951,
     "end_time": "2026-10-02T14:45:56.912070+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:45:56.910119+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "## CaseReader Constructor\n",
    "\n",
    "The call signature for the `CaseReader` constructor is:\n",
    "\n",
    "```{eval-rst}\n",
    "    .. automethod:: openmdao.recorders.sqlite_reader.SqliteCaseReader.__init__\n",
    "        :noindex:\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9c01d904",
   "metadata": {
    "papermill": {
     "duration": 0.003762,
     "end_time": "2026-10-02T14:45:56.919885+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:45:56.916123+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "## Determining What Sources and Variables Were Recorded\n",
    "\n",
    "The `CaseReader` object provides methods to determine which objects in the original problem were sources\n",
    "for for the recorded cases and what variables they recorded. Sources can include the problem, driver, components and solvers.\n",
    "\n",
    "The `list_sources` method provides a list of the names of objects that are the sources of recorded data\n",
    "in the file.\n",
    "\n",
    "```{eval-rst}\n",
    ".. automethod:: openmdao.recorders.base_case_reader.BaseCaseReader.list_sources\n",
    "    :noindex:\n",
    "```\n",
    "\n",
    "The complementary `list_source_vars` method will provide a list of the input and output variables recorded\n",
    "for a given source.\n",
    "\n",
    "```{eval-rst}\n",
    ".. automethod:: openmdao.recorders.base_case_reader.BaseCaseReader.list_source_vars\n",
    "    :noindex:\n",
    "```\n",
    "\n",
    "Here is an example of their usage:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "03c50f56",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:45:56.930181Z",
     "iopub.status.busy": "2026-10-02T14:45:56.929998Z",
     "iopub.status.idle": "2026-10-02T14:46:00.158924Z",
     "shell.execute_reply": "2026-10-02T14:46:00.158234Z"
    },
    "papermill": {
     "duration": 3.234805,
     "end_time": "2026-10-02T14:46:00.159714+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:45:56.924909+00:00",
     "status": "completed"
    },
    "tags": [
     "remove-input"
    ]
   },
   "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\">SellarMDA</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.</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=\"n\">cycle</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_subsystem</span><span class=\"p\">(</span><span class=\"s1\">&#39;cycle&#39;</span><span class=\"p\">,</span> <span class=\"n\">om</span><span class=\"o\">.</span><span class=\"n\">Group</span><span class=\"p\">(),</span> <span class=\"n\">promotes</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"s1\">&#39;*&#39;</span><span class=\"p\">])</span>\n        <span class=\"n\">cycle</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\">SellarDis1</span><span class=\"p\">(),</span> <span class=\"n\">promotes_inputs</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"s1\">&#39;x&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;z&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;y2&#39;</span><span class=\"p\">],</span>\n                            <span class=\"n\">promotes_outputs</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"s1\">&#39;y1&#39;</span><span class=\"p\">])</span>\n        <span class=\"n\">cycle</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\">SellarDis2</span><span class=\"p\">(),</span> <span class=\"n\">promotes_inputs</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>\n                            <span class=\"n\">promotes_outputs</span><span class=\"o\">=</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\n        <span class=\"c1\"># Nonlinear Block Gauss Seidel is a gradient free solver</span>\n        <span class=\"n\">cycle</span><span class=\"o\">.</span><span class=\"n\">nonlinear_solver</span> <span class=\"o\">=</span> <span class=\"n\">om</span><span class=\"o\">.</span><span class=\"n\">NonlinearBlockGS</span><span class=\"p\">()</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_subsystem</span><span class=\"p\">(</span><span class=\"s1\">&#39;obj_cmp&#39;</span><span class=\"p\">,</span> <span class=\"n\">om</span><span class=\"o\">.</span><span class=\"n\">ExecComp</span><span class=\"p\">(</span><span class=\"s1\">&#39;obj = x**2 + z[1] + y1 + exp(-y2)&#39;</span><span class=\"p\">,</span>\n                                                  <span class=\"n\">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\">x</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;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> <span class=\"s1\">&#39;obj&#39;</span><span class=\"p\">])</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_subsystem</span><span class=\"p\">(</span><span class=\"s1\">&#39;con_cmp1&#39;</span><span class=\"p\">,</span> <span class=\"n\">om</span><span class=\"o\">.</span><span class=\"n\">ExecComp</span><span class=\"p\">(</span><span class=\"s1\">&#39;con1 = 3.16 - y1&#39;</span><span class=\"p\">),</span> <span class=\"n\">promotes</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\">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</pre></div>\n",
      "application/papermill.record/text/latex": "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n\\PY{k}{class}\\PY{+w}{ }\\PY{n+nc}{SellarMDA}\\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.}\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}{cycle} \\PY{o}{=} \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{add\\PYZus{}subsystem}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{cycle}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{om}\\PY{o}{.}\\PY{n}{Group}\\PY{p}{(}\\PY{p}{)}\\PY{p}{,} \\PY{n}{promotes}\\PY{o}{=}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{*}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\\PY{p}{)}\n        \\PY{n}{cycle}\\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}{SellarDis1}\\PY{p}{(}\\PY{p}{)}\\PY{p}{,} \\PY{n}{promotes\\PYZus{}inputs}\\PY{o}{=}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{x}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{z}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{y2}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\\PY{p}{,}\n                            \\PY{n}{promotes\\PYZus{}outputs}\\PY{o}{=}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{y1}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\\PY{p}{)}\n        \\PY{n}{cycle}\\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}{SellarDis2}\\PY{p}{(}\\PY{p}{)}\\PY{p}{,} \\PY{n}{promotes\\PYZus{}inputs}\\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{p}{,}\n                            \\PY{n}{promotes\\PYZus{}outputs}\\PY{o}{=}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{y2}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\\PY{p}{)}\n\n        \\PY{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\n        \\PY{c+c1}{\\PYZsh{} Nonlinear Block Gauss Seidel is a gradient free solver}\n        \\PY{n}{cycle}\\PY{o}{.}\\PY{n}{nonlinear\\PYZus{}solver} \\PY{o}{=} \\PY{n}{om}\\PY{o}{.}\\PY{n}{NonlinearBlockGS}\\PY{p}{(}\\PY{p}{)}\n\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{add\\PYZus{}subsystem}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{obj\\PYZus{}cmp}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{om}\\PY{o}{.}\\PY{n}{ExecComp}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{obj = x**2 + z[1] + y1 + exp(\\PYZhy{}y2)}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,}\n                                                  \\PY{n}{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}{x}\\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}{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{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{obj}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\\PY{p}{)}\n\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{add\\PYZus{}subsystem}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{con\\PYZus{}cmp1}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{om}\\PY{o}{.}\\PY{n}{ExecComp}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{con1 = 3.16 \\PYZhy{} y1}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{)}\\PY{p}{,} \\PY{n}{promotes}\\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{p}{,} \\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\\end{Verbatim}\n",
      "application/papermill.record/text/plain": "class SellarMDA(om.Group):\n    \"\"\"\n    Group containing the Sellar MDA.\n    \"\"\"\n\n    def setup(self):\n        cycle = self.add_subsystem('cycle', om.Group(), promotes=['*'])\n        cycle.add_subsystem('d1', SellarDis1(), promotes_inputs=['x', 'z', 'y2'],\n                            promotes_outputs=['y1'])\n        cycle.add_subsystem('d2', SellarDis2(), promotes_inputs=['z', 'y1'],\n                            promotes_outputs=['y2'])\n\n        self.set_input_defaults('x', 1.0)\n        self.set_input_defaults('z', np.array([5.0, 2.0]))\n\n        # Nonlinear Block Gauss Seidel is a gradient free solver\n        cycle.nonlinear_solver = om.NonlinearBlockGS()\n\n        self.add_subsystem('obj_cmp', om.ExecComp('obj = x**2 + z[1] + y1 + exp(-y2)',\n                                                  z=np.array([0.0, 0.0]), x=0.0),\n                           promotes=['x', 'z', 'y1', 'y2', 'obj'])\n\n        self.add_subsystem('con_cmp1', om.ExecComp('con1 = 3.16 - y1'), promotes=['con1', 'y1'])\n        self.add_subsystem('con_cmp2', om.ExecComp('con2 = y2 - 24.0'), promotes=['con2', 'y2'])"
     },
     "metadata": {
      "scrapbook": {
       "mime_prefix": "application/papermill.record/",
       "name": "code_src86"
      }
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "from openmdao.utils.notebook_utils import get_code\n",
    "from myst_nb import glue\n",
    "glue(\"code_src86\", get_code(\"openmdao.test_suite.components.sellar_feature.SellarMDA\"), display=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1ba94bcb",
   "metadata": {
    "papermill": {
     "duration": 0.002709,
     "end_time": "2026-10-02T14:46:00.165261+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:00.162552+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    ":::{dropdown} `SellarMDA` class definition \n",
    "\n",
    "{glue:}`code_src86`\n",
    ":::"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "883dd3e9",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:46:00.170535Z",
     "iopub.status.busy": "2026-10-02T14:46:00.170311Z",
     "iopub.status.idle": "2026-10-02T14:46:02.905158Z",
     "shell.execute_reply": "2026-10-02T14:46:02.904360Z"
    },
    "papermill": {
     "duration": 2.738321,
     "end_time": "2026-10-02T14:46:02.905799+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:00.167478+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[runnervm8df0l:10366] pml_ucx.c:313  Error: Failed to create UCP worker\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1790952361.440159] [runnervm8df0l:10366:0]        ib_iface.c:1269 UCX  ERROR mana_0: iface 0x559d68c8c460 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",
      "[1790952361.440455] [runnervm8df0l:10366:0]      ucp_worker.c:1412 UCX  ERROR uct_iface_open(ud_verbs/mana_0:1) failed: Input/output error\n"
     ]
    }
   ],
   "source": [
    "import openmdao.api as om\n",
    "from openmdao.test_suite.components.sellar_feature import SellarMDA\n",
    "\n",
    "import numpy as np\n",
    "\n",
    "# define Sellar MDA problem\n",
    "prob = om.Problem(name='case_reader', model=SellarMDA())\n",
    "\n",
    "model = prob.model\n",
    "model.add_design_var('z', lower=np.array([-10.0, 0.0]),\n",
    "                          upper=np.array([10.0, 10.0]))\n",
    "model.add_design_var('x', lower=0.0, upper=10.0)\n",
    "model.add_objective('obj')\n",
    "model.add_constraint('con1', upper=0.0)\n",
    "model.add_constraint('con2', upper=0.0)\n",
    "\n",
    "prob.driver = om.ScipyOptimizeDriver(optimizer='SLSQP', tol=1e-9, disp=False)\n",
    "\n",
    "# add recorder to the driver, model and solver\n",
    "recorder = om.SqliteRecorder('case_reader.sql')\n",
    "\n",
    "prob.driver.add_recorder(recorder)\n",
    "model.add_recorder(recorder)\n",
    "model.nonlinear_solver.add_recorder(recorder)\n",
    "\n",
    "# run the problem\n",
    "prob.setup()\n",
    "prob.set_solver_print(0)\n",
    "prob.run_driver()\n",
    "prob.cleanup()\n",
    "\n",
    "cr = om.CaseReader(prob.get_outputs_dir() / 'case_reader.sql')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "22919541",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:46:02.910758Z",
     "iopub.status.busy": "2026-10-02T14:46:02.910435Z",
     "iopub.status.idle": "2026-10-02T14:46:02.914871Z",
     "shell.execute_reply": "2026-10-02T14:46:02.914343Z"
    },
    "papermill": {
     "duration": 0.007912,
     "end_time": "2026-10-02T14:46:02.915761+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:02.907849+00:00",
     "status": "completed"
    },
    "scrolled": true,
    "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;\">Sources</th></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">driver</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">root.nonlinear_solver</td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">root</td></tr>\n",
       "    </table>\n",
       "</body>\n",
       "</html>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "sources = cr.list_sources()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "eb98fc02",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:46:02.921233Z",
     "iopub.status.busy": "2026-10-02T14:46:02.921105Z",
     "iopub.status.idle": "2026-10-02T14:46:02.923370Z",
     "shell.execute_reply": "2026-10-02T14:46:02.922712Z"
    },
    "papermill": {
     "duration": 0.005544,
     "end_time": "2026-10-02T14:46:02.923808+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:02.918264+00:00",
     "status": "completed"
    },
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "assert sorted(sources) == ['driver', 'root', 'root.nonlinear_solver']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "3f3d320f",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:46:02.927878Z",
     "iopub.status.busy": "2026-10-02T14:46:02.927751Z",
     "iopub.status.idle": "2026-10-02T14:46:02.931340Z",
     "shell.execute_reply": "2026-10-02T14:46:02.930591Z"
    },
    "papermill": {
     "duration": 0.006178,
     "end_time": "2026-10-02T14:46:02.931802+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:02.925624+00:00",
     "status": "completed"
    },
    "scrolled": true,
    "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;\">inputs</th><th style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; background-color: #E9E9E9; text-align: left;\">outputs</th><th style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; background-color: #E9E9E9; text-align: left;\">residuals</th></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><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;\">x</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\"></td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><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;\">z</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\"></td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><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;\">con1</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\"></td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><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;\">con2</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\"></td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><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;\">obj</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\"></td></tr>\n",
       "    </table>\n",
       "</body>\n",
       "</html>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "driver_vars = cr.list_source_vars('driver')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "e567dc69",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:46:02.935951Z",
     "iopub.status.busy": "2026-10-02T14:46:02.935781Z",
     "iopub.status.idle": "2026-10-02T14:46:02.938715Z",
     "shell.execute_reply": "2026-10-02T14:46:02.938062Z"
    },
    "papermill": {
     "duration": 0.005639,
     "end_time": "2026-10-02T14:46:02.939108+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:02.933469+00:00",
     "status": "completed"
    },
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "assert driver_vars['inputs'] == []\n",
    "assert set(driver_vars['outputs']) == {'con1', 'con2', 'obj', 'x', 'z'}\n",
    "assert driver_vars['residuals'] == []"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "f051f3f5",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:46:02.943247Z",
     "iopub.status.busy": "2026-10-02T14:46:02.943070Z",
     "iopub.status.idle": "2026-10-02T14:46:02.946633Z",
     "shell.execute_reply": "2026-10-02T14:46:02.945974Z"
    },
    "papermill": {
     "duration": 0.00631,
     "end_time": "2026-10-02T14:46:02.947086+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:02.940776+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;\">inputs</th><th style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; background-color: #E9E9E9; text-align: left;\">outputs</th><th style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; background-color: #E9E9E9; text-align: left;\">residuals</th></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">con_cmp1.y1</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">x</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">x</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">con_cmp2.y2</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">z</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">z</td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">cycle.d1.x</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">con1</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">con1</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">cycle.d1.y2</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">con2</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">con2</td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">cycle.d1.z</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">y1</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">y1</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">cycle.d2.y1</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">y2</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">y2</td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">cycle.d2.z</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">obj</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">obj</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">obj_cmp.x</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;\"></td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">obj_cmp.y1</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;\"></td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">obj_cmp.y2</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;\"></td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">obj_cmp.z</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;\"></td></tr>\n",
       "    </table>\n",
       "</body>\n",
       "</html>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "model_vars = cr.list_source_vars('root')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "19be18a7",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:46:02.951300Z",
     "iopub.status.busy": "2026-10-02T14:46:02.951137Z",
     "iopub.status.idle": "2026-10-02T14:46:02.953976Z",
     "shell.execute_reply": "2026-10-02T14:46:02.953366Z"
    },
    "papermill": {
     "duration": 0.005584,
     "end_time": "2026-10-02T14:46:02.954394+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:02.948810+00:00",
     "status": "completed"
    },
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "assert set(model_vars['inputs']) == {'obj_cmp.z', 'cycle.d1.z', 'cycle.d2.y1', 'con_cmp2.y2',\n",
    "                                     'cycle.d1.x', 'obj_cmp.y1', 'obj_cmp.y2', 'con_cmp1.y1',\n",
    "                                     'obj_cmp.x', 'cycle.d2.z', 'cycle.d1.y2'}\n",
    "assert set(model_vars['outputs']) == {'con1', 'con2', 'obj', 'x', 'y1', 'y2', 'z'}\n",
    "assert set(model_vars['residuals']) == {'con1', 'con2', 'obj', 'x', 'y1', 'y2', 'z'}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "53d7833b",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:46:02.964442Z",
     "iopub.status.busy": "2026-10-02T14:46:02.964316Z",
     "iopub.status.idle": "2026-10-02T14:46:02.967355Z",
     "shell.execute_reply": "2026-10-02T14:46:02.966721Z"
    },
    "papermill": {
     "duration": 0.010967,
     "end_time": "2026-10-02T14:46:02.967789+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:02.956822+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;\">inputs</th><th style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; background-color: #E9E9E9; text-align: left;\">outputs</th><th style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; background-color: #E9E9E9; text-align: left;\">residuals</th></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">con_cmp1.y1</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">x</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\"></td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">con_cmp2.y2</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">z</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\"></td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">cycle.d1.z</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">con1</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\"></td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">cycle.d1.x</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">con2</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\"></td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">cycle.d1.y2</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">y1</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\"></td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">cycle.d2.z</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">y2</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\"></td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">cycle.d2.y1</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">obj</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\"></td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">obj_cmp.x</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;\"></td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">obj_cmp.y1</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;\"></td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">obj_cmp.y2</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;\"></td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">obj_cmp.z</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;\"></td></tr>\n",
       "    </table>\n",
       "</body>\n",
       "</html>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "solver_vars = cr.list_source_vars('root.nonlinear_solver')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "5a38b551",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:46:02.972320Z",
     "iopub.status.busy": "2026-10-02T14:46:02.972200Z",
     "iopub.status.idle": "2026-10-02T14:46:02.974626Z",
     "shell.execute_reply": "2026-10-02T14:46:02.974038Z"
    },
    "papermill": {
     "duration": 0.005557,
     "end_time": "2026-10-02T14:46:02.975114+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:02.969557+00:00",
     "status": "completed"
    },
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "assert set(solver_vars['inputs']) == {'obj_cmp.z', 'cycle.d1.z', 'cycle.d2.y1', 'con_cmp2.y2',\n",
    "                                      'cycle.d1.x', 'obj_cmp.y1', 'obj_cmp.y2', 'con_cmp1.y1',\n",
    "                                      'obj_cmp.x', 'cycle.d2.z', 'cycle.d1.y2'}\n",
    "assert set(solver_vars['outputs']) == {'con1', 'con2', 'obj', 'x', 'y1', 'y2', 'z'}\n",
    "assert solver_vars['residuals'] == []"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e6fbf568",
   "metadata": {
    "papermill": {
     "duration": 0.001724,
     "end_time": "2026-10-02T14:46:02.980469+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:02.978745+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "## Case Names\n",
    "\n",
    "The `CaseReader` provides access to `Case` objects, each of which encapsulates a data point recorded by\n",
    "one of the sources.\n",
    "\n",
    "`Case` objects are uniquely identified in a case recorder file by their case names. A case name is a string.\n",
    "As an example, here is a case name:\n",
    "\n",
    "    'rank0:ScipyOptimize_SLSQP|1|root._solve_nonlinear|1'\n",
    "\n",
    "The first part of the case name indicates which rank or process that the case was recorded from. \n",
    "The remainder of the case name shows the hierarchical path to the object that was recorded along \n",
    "with the iteration counts for each object along the path. It follows a pattern of repeated pairs of\n",
    "\n",
    "    - object name ( problem, driver, system, or solver )\n",
    "    - iteration count\n",
    "\n",
    "These are separated by the `|` character.\n",
    "\n",
    "So in the given example, the case is:\n",
    "\n",
    "    - from rank 0\n",
    "    - the first iteration of the driver, `ScipyOptimize_SLSQP`\n",
    "    - the first execution of the `root` system which is the top-level model"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8290fd57",
   "metadata": {
    "papermill": {
     "duration": 0.00175,
     "end_time": "2026-10-02T14:46:02.984206+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:02.982456+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "\n",
    "## Getting Names of the Cases\n",
    "\n",
    "The `list_cases` method returns the names of the cases in the order in which\n",
    "the cases were executed. You can optionally request cases only from a specific `source`.\n",
    "\n",
    "```{eval-rst}\n",
    ".. automethod:: openmdao.recorders.base_case_reader.BaseCaseReader.list_cases\n",
    "    :noindex:\n",
    "```\n",
    "\n",
    "There are two optional arguments to the `list_cases` method that affect what is returned.\n",
    "\n",
    "    - recurse: causes the returned value to include child cases.\n",
    "\n",
    "    - flat: works in conjunction with the `recurse` argument to determine if the returned\n",
    "      results are in the form of a list or nested dict. If recurse=True, flat=False, and there\n",
    "      are child cases, then the returned value is a nested ordered dict. Otherwise, it is a list.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "84a9b4f5",
   "metadata": {
    "papermill": {
     "duration": 0.001715,
     "end_time": "2026-10-02T14:46:02.987727+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:02.986012+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "\n",
    "## Accessing Cases\n",
    "\n",
    "Getting information from the cases is a two-step process. First, you need to get access to the Case object and then you can call a variety of methods on the Case object to get values from it. The second step is described on the [Getting Data from a Case](case_reader_data.ipynb) page.\n",
    "\n",
    "There are two methods used to get a specific `Case`:\n",
    "\n",
    "    - get_cases\n",
    "    - get_case"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "50503a23",
   "metadata": {
    "papermill": {
     "duration": 0.00171,
     "end_time": "2026-10-02T14:46:02.991152+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:02.989442+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "\n",
    "### Accessing Cases Using get_cases Method\n",
    "\n",
    "The `get_cases` method provides a quick and easy way to iterate over all the cases.\n",
    "\n",
    "```{eval-rst}\n",
    ".. automethod:: openmdao.recorders.base_case_reader.BaseCaseReader.get_cases\n",
    "    :noindex:\n",
    "```\n",
    "This method is similar to the `list_cases` method in that it has the two optional arguments\n",
    "`recurse` and `flat` to control what is returned as described above.\n",
    "\n",
    "Here is an example of its usage:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "87aeabca",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:46:02.995504Z",
     "iopub.status.busy": "2026-10-02T14:46:02.995368Z",
     "iopub.status.idle": "2026-10-02T14:46:03.198892Z",
     "shell.execute_reply": "2026-10-02T14:46:03.197978Z"
    },
    "papermill": {
     "duration": 0.206551,
     "end_time": "2026-10-02T14:46:03.199447+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:02.992896+00:00",
     "status": "completed"
    },
    "scrolled": true,
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Optimization terminated successfully    (Exit mode 0)\n",
      "            Current function value: 3.1833955346293656\n",
      "            Iterations: 8\n",
      "            Function evaluations: 9\n",
      "            Gradient evaluations: 8\n",
      "Optimization Complete\n",
      "-----------------------------------\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/runner/work/OpenMDAO/OpenMDAO/.pixi/envs/dev/lib/python3.13/site-packages/openmdao/core/problem.py:384: OpenMDAOWarning:The problem name 'case_reader' already exists\n"
     ]
    }
   ],
   "source": [
    "import openmdao.api as om\n",
    "from openmdao.test_suite.components.sellar_feature import SellarMDA\n",
    "\n",
    "import numpy as np\n",
    "\n",
    "prob = om.Problem(name='case_reader', model=SellarMDA())\n",
    "\n",
    "model = prob.model\n",
    "model.add_design_var('z', lower=np.array([-10.0, 0.0]),\n",
    "                          upper=np.array([10.0, 10.0]))\n",
    "model.add_design_var('x', lower=0.0, upper=10.0)\n",
    "model.add_objective('obj')\n",
    "model.add_constraint('con1', upper=0.0)\n",
    "model.add_constraint('con2', upper=0.0)\n",
    "\n",
    "driver = prob.driver = om.ScipyOptimizeDriver(optimizer='SLSQP', tol=1e-5)\n",
    "driver.add_recorder(om.SqliteRecorder('case_reader.sql'))\n",
    "\n",
    "prob.setup()\n",
    "prob.set_solver_print(0)\n",
    "prob.run_driver()\n",
    "prob.cleanup()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "37af431b",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:46:03.205007Z",
     "iopub.status.busy": "2026-10-02T14:46:03.204852Z",
     "iopub.status.idle": "2026-10-02T14:46:03.211492Z",
     "shell.execute_reply": "2026-10-02T14:46:03.210802Z"
    },
    "papermill": {
     "duration": 0.010367,
     "end_time": "2026-10-02T14:46:03.212296+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:03.201929+00:00",
     "status": "completed"
    },
    "scrolled": false,
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "rank0:ScipyOptimize_SLSQP|0 ['con1', 'con2', 'obj', 'x', 'z']\n",
      "rank0:ScipyOptimize_SLSQP|1 ['con1', 'con2', 'obj', 'x', 'z']\n",
      "rank0:ScipyOptimize_SLSQP|2 ['con1', 'con2', 'obj', 'x', 'z']\n",
      "rank0:ScipyOptimize_SLSQP|3 ['con1', 'con2', 'obj', 'x', 'z']\n",
      "rank0:ScipyOptimize_SLSQP|4 ['con1', 'con2', 'obj', 'x', 'z']\n",
      "rank0:ScipyOptimize_SLSQP|5 ['con1', 'con2', 'obj', 'x', 'z']\n",
      "rank0:ScipyOptimize_SLSQP|6 ['con1', 'con2', 'obj', 'x', 'z']\n",
      "rank0:ScipyOptimize_SLSQP|7 ['con1', 'con2', 'obj', 'x', 'z']\n",
      "rank0:ScipyOptimize_SLSQP|8 ['con1', 'con2', 'obj', 'x', 'z']\n",
      "rank0:ScipyOptimize_SLSQP|9 ['con1', 'con2', 'obj', 'x', 'z']\n"
     ]
    }
   ],
   "source": [
    "cr = om.CaseReader(prob.get_outputs_dir() / 'case_reader.sql')\n",
    "cases = cr.get_cases()\n",
    "for case in cases:\n",
    "    print(case.name, sorted(case.outputs))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "3c215c17",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:46:03.220740Z",
     "iopub.status.busy": "2026-10-02T14:46:03.220592Z",
     "iopub.status.idle": "2026-10-02T14:46:03.223207Z",
     "shell.execute_reply": "2026-10-02T14:46:03.222573Z"
    },
    "papermill": {
     "duration": 0.008441,
     "end_time": "2026-10-02T14:46:03.223637+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:03.215196+00:00",
     "status": "completed"
    },
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "assert len(cases) == driver.iter_count\n",
    "for i, case in enumerate(cases):\n",
    "    assert case.name == f\"rank0:ScipyOptimize_SLSQP|{i}\", f\"unexpected case name: {case.name}\"\n",
    "    assert sorted(case.outputs) == ['con1', 'con2', 'obj', 'x', 'z']"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fcb6643f",
   "metadata": {
    "papermill": {
     "duration": 0.001786,
     "end_time": "2026-10-02T14:46:03.227261+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:03.225475+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "\n",
    "### Accessing Cases Using get_case Method\n",
    "\n",
    "The `get_case` method returns a `Case` object given a case name.\n",
    "```{eval-rst}\n",
    ".. automethod:: openmdao.recorders.base_case_reader.BaseCaseReader.get_case\n",
    "    :noindex:\n",
    "```\n",
    "You can use the `get_case` method to get a specific case from the list of case names\n",
    "returned by `list_cases` as shown here:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "54b0ecd4",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:46:03.232020Z",
     "iopub.status.busy": "2026-10-02T14:46:03.231881Z",
     "iopub.status.idle": "2026-10-02T14:46:03.235093Z",
     "shell.execute_reply": "2026-10-02T14:46:03.234588Z"
    },
    "papermill": {
     "duration": 0.006683,
     "end_time": "2026-10-02T14:46:03.235744+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:03.229061+00:00",
     "status": "completed"
    },
    "scrolled": false,
    "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;\">driver</th></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:ScipyOptimize_SLSQP|0</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:ScipyOptimize_SLSQP|1</td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:ScipyOptimize_SLSQP|2</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:ScipyOptimize_SLSQP|3</td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:ScipyOptimize_SLSQP|4</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:ScipyOptimize_SLSQP|5</td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:ScipyOptimize_SLSQP|6</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:ScipyOptimize_SLSQP|7</td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:ScipyOptimize_SLSQP|8</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:ScipyOptimize_SLSQP|9</td></tr>\n",
       "    </table>\n",
       "</body>\n",
       "</html>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "case_names = cr.list_cases()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "3cee68c7",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:46:03.241708Z",
     "iopub.status.busy": "2026-10-02T14:46:03.241569Z",
     "iopub.status.idle": "2026-10-02T14:46:03.243856Z",
     "shell.execute_reply": "2026-10-02T14:46:03.243352Z"
    },
    "papermill": {
     "duration": 0.005971,
     "end_time": "2026-10-02T14:46:03.244462+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:03.238491+00:00",
     "status": "completed"
    },
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "assert len(case_names) == driver.iter_count\n",
    "for i, case_name in enumerate(case_names):\n",
    "    assert case_name == f\"rank0:ScipyOptimize_SLSQP|{i}\", f\"unexpected case name: {case_name}\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "127b0b16",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:46:03.249107Z",
     "iopub.status.busy": "2026-10-02T14:46:03.248945Z",
     "iopub.status.idle": "2026-10-02T14:46:03.251762Z",
     "shell.execute_reply": "2026-10-02T14:46:03.251032Z"
    },
    "papermill": {
     "duration": 0.005734,
     "end_time": "2026-10-02T14:46:03.252231+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:03.246497+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "rank0:ScipyOptimize_SLSQP|0 ['con1', 'con2', 'obj', 'x', 'z']\n"
     ]
    }
   ],
   "source": [
    "# access a Case by name (e.g. first case)\n",
    "case = cr.get_case(\"rank0:ScipyOptimize_SLSQP|0\")\n",
    "print(case.name, sorted(case.outputs))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "badcc664",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:46:03.257093Z",
     "iopub.status.busy": "2026-10-02T14:46:03.256931Z",
     "iopub.status.idle": "2026-10-02T14:46:03.259234Z",
     "shell.execute_reply": "2026-10-02T14:46:03.258674Z"
    },
    "papermill": {
     "duration": 0.005262,
     "end_time": "2026-10-02T14:46:03.259665+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:03.254403+00:00",
     "status": "completed"
    },
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "assert case.name == \"rank0:ScipyOptimize_SLSQP|0\", f\"unexpected case name: {case.name}\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "940e6ce3",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:46:03.290096Z",
     "iopub.status.busy": "2026-10-02T14:46:03.289940Z",
     "iopub.status.idle": "2026-10-02T14:46:03.292579Z",
     "shell.execute_reply": "2026-10-02T14:46:03.291874Z"
    },
    "papermill": {
     "duration": 0.005835,
     "end_time": "2026-10-02T14:46:03.293103+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:03.287268+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "rank0:ScipyOptimize_SLSQP|0 ['con1', 'con2', 'obj', 'x', 'z']\n"
     ]
    }
   ],
   "source": [
    "# access a Case by index (e.g. first case)\n",
    "case = cr.get_case(0)\n",
    "print(case.name, sorted(case.outputs))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "fb753f6b",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:46:03.299125Z",
     "iopub.status.busy": "2026-10-02T14:46:03.299002Z",
     "iopub.status.idle": "2026-10-02T14:46:03.301165Z",
     "shell.execute_reply": "2026-10-02T14:46:03.300612Z"
    },
    "papermill": {
     "duration": 0.005789,
     "end_time": "2026-10-02T14:46:03.301628+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:03.295839+00:00",
     "status": "completed"
    },
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "assert case.name == \"rank0:ScipyOptimize_SLSQP|0\", f\"unexpected case name: {case.name}\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "fef88933",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:46:03.306238Z",
     "iopub.status.busy": "2026-10-02T14:46:03.306113Z",
     "iopub.status.idle": "2026-10-02T14:46:03.308625Z",
     "shell.execute_reply": "2026-10-02T14:46:03.307974Z"
    },
    "papermill": {
     "duration": 0.005622,
     "end_time": "2026-10-02T14:46:03.309243+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:03.303621+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "rank0:ScipyOptimize_SLSQP|9 ['con1', 'con2', 'obj', 'x', 'z']\n"
     ]
    }
   ],
   "source": [
    "# access a Case by index (e.g. last case)\n",
    "case = cr.get_case(-1)\n",
    "print(case.name, sorted(case.outputs))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "9a0e1261",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:46:03.383640Z",
     "iopub.status.busy": "2026-10-02T14:46:03.383438Z",
     "iopub.status.idle": "2026-10-02T14:46:03.386536Z",
     "shell.execute_reply": "2026-10-02T14:46:03.385668Z"
    },
    "papermill": {
     "duration": 0.008694,
     "end_time": "2026-10-02T14:46:03.387262+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:03.378568+00:00",
     "status": "completed"
    },
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "assert case.name == f\"rank0:ScipyOptimize_SLSQP|{driver.iter_count-1}\", f\"unexpected case name: {case.name}\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "ac659644",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:46:03.394267Z",
     "iopub.status.busy": "2026-10-02T14:46:03.394116Z",
     "iopub.status.idle": "2026-10-02T14:46:03.397306Z",
     "shell.execute_reply": "2026-10-02T14:46:03.396504Z"
    },
    "papermill": {
     "duration": 0.007405,
     "end_time": "2026-10-02T14:46:03.397858+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:03.390453+00:00",
     "status": "completed"
    },
    "scrolled": true,
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "rank0:ScipyOptimize_SLSQP|0 ['con1', 'con2', 'obj', 'x', 'z']\n",
      "rank0:ScipyOptimize_SLSQP|1 ['con1', 'con2', 'obj', 'x', 'z']\n",
      "rank0:ScipyOptimize_SLSQP|2 ['con1', 'con2', 'obj', 'x', 'z']\n",
      "rank0:ScipyOptimize_SLSQP|3 ['con1', 'con2', 'obj', 'x', 'z']\n",
      "rank0:ScipyOptimize_SLSQP|4 ['con1', 'con2', 'obj', 'x', 'z']\n",
      "rank0:ScipyOptimize_SLSQP|5 ['con1', 'con2', 'obj', 'x', 'z']\n",
      "rank0:ScipyOptimize_SLSQP|6 ['con1', 'con2', 'obj', 'x', 'z']\n",
      "rank0:ScipyOptimize_SLSQP|7 ['con1', 'con2', 'obj', 'x', 'z']\n",
      "rank0:ScipyOptimize_SLSQP|8 ['con1', 'con2', 'obj', 'x', 'z']\n",
      "rank0:ScipyOptimize_SLSQP|9 ['con1', 'con2', 'obj', 'x', 'z']\n"
     ]
    }
   ],
   "source": [
    "# get each case by looping over case names\n",
    "for name in case_names:\n",
    "    case = cr.get_case(name)\n",
    "    print(case.name, sorted(case.outputs))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "58726e5a",
   "metadata": {
    "papermill": {
     "duration": 0.002177,
     "end_time": "2026-10-02T14:46:03.402231+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:03.400054+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "### Processing a Nested Dictionary of Its Child Cases\n",
    "\n",
    "The following example demonstrates selecting a case from a case list and processing a nested\n",
    "dictionary of its child cases."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "dc698033",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:46:03.407875Z",
     "iopub.status.busy": "2026-10-02T14:46:03.407674Z",
     "iopub.status.idle": "2026-10-02T14:46:04.434358Z",
     "shell.execute_reply": "2026-10-02T14:46:04.433617Z"
    },
    "papermill": {
     "duration": 1.030768,
     "end_time": "2026-10-02T14:46:04.435369+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:03.404601+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/runner/work/OpenMDAO/OpenMDAO/.pixi/envs/dev/lib/python3.13/site-packages/openmdao/core/problem.py:384: OpenMDAOWarning:The problem name 'case_reader' already exists\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Optimization terminated successfully    (Exit mode 0)\n",
      "            Current function value: 3.1833955346293656\n",
      "            Iterations: 8\n",
      "            Function evaluations: 9\n",
      "            Gradient evaluations: 8\n",
      "Optimization Complete\n",
      "-----------------------------------\n"
     ]
    }
   ],
   "source": [
    "import openmdao.api as om\n",
    "from openmdao.test_suite.components.sellar_feature import SellarMDA\n",
    "\n",
    "import numpy as np\n",
    "\n",
    "# define Sellar MDA problem\n",
    "prob = om.Problem(name='case_reader', model=SellarMDA())\n",
    "\n",
    "model = prob.model\n",
    "model.add_design_var('z', lower=np.array([-10.0, 0.0]),\n",
    "                          upper=np.array([10.0, 10.0]))\n",
    "model.add_design_var('x', lower=0.0, upper=10.0)\n",
    "model.add_objective('obj')\n",
    "model.add_constraint('con1', upper=0.0)\n",
    "model.add_constraint('con2', upper=0.0)\n",
    "\n",
    "prob.driver = om.ScipyOptimizeDriver(optimizer='SLSQP', tol=1e-5)\n",
    "\n",
    "# add recorder to the driver, model and solver\n",
    "recorder = om.SqliteRecorder('case_reader.sql')\n",
    "\n",
    "prob.driver.add_recorder(recorder)\n",
    "model.add_recorder(recorder)\n",
    "model.nonlinear_solver.add_recorder(recorder)\n",
    "\n",
    "# run the problem\n",
    "prob.setup()\n",
    "prob.set_solver_print(0)\n",
    "prob.run_driver()\n",
    "prob.cleanup()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "cf8549cd",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:46:04.443189Z",
     "iopub.status.busy": "2026-10-02T14:46:04.442984Z",
     "iopub.status.idle": "2026-10-02T14:46:04.459119Z",
     "shell.execute_reply": "2026-10-02T14:46:04.458539Z"
    },
    "papermill": {
     "duration": 0.021251,
     "end_time": "2026-10-02T14:46:04.460001+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:04.438750+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;\">driver</th></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:ScipyOptimize_SLSQP|0|root._solve_nonlinear|0|NLRunOnce|0</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:ScipyOptimize_SLSQP|0|root._solve_nonlinear|0</td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:ScipyOptimize_SLSQP|0</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:ScipyOptimize_SLSQP|1|root._solve_nonlinear|1|NLRunOnce|0</td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:ScipyOptimize_SLSQP|1|root._solve_nonlinear|1</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:ScipyOptimize_SLSQP|1</td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:ScipyOptimize_SLSQP|2|root._solve_nonlinear|2|NLRunOnce|0</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:ScipyOptimize_SLSQP|2|root._solve_nonlinear|2</td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:ScipyOptimize_SLSQP|2</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:ScipyOptimize_SLSQP|3|root._solve_nonlinear|3|NLRunOnce|0</td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:ScipyOptimize_SLSQP|3|root._solve_nonlinear|3</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:ScipyOptimize_SLSQP|3</td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:ScipyOptimize_SLSQP|4|root._solve_nonlinear|4|NLRunOnce|0</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:ScipyOptimize_SLSQP|4|root._solve_nonlinear|4</td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:ScipyOptimize_SLSQP|4</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:ScipyOptimize_SLSQP|5|root._solve_nonlinear|5|NLRunOnce|0</td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:ScipyOptimize_SLSQP|5|root._solve_nonlinear|5</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:ScipyOptimize_SLSQP|5</td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:ScipyOptimize_SLSQP|6|root._solve_nonlinear|6|NLRunOnce|0</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:ScipyOptimize_SLSQP|6|root._solve_nonlinear|6</td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:ScipyOptimize_SLSQP|6</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:ScipyOptimize_SLSQP|7|root._solve_nonlinear|7|NLRunOnce|0</td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:ScipyOptimize_SLSQP|7|root._solve_nonlinear|7</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:ScipyOptimize_SLSQP|7</td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:ScipyOptimize_SLSQP|8|root._solve_nonlinear|8|NLRunOnce|0</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:ScipyOptimize_SLSQP|8|root._solve_nonlinear|8</td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:ScipyOptimize_SLSQP|8</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:ScipyOptimize_SLSQP|9|root._solve_nonlinear|9|NLRunOnce|0</td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:ScipyOptimize_SLSQP|9|root._solve_nonlinear|9</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:ScipyOptimize_SLSQP|9</td></tr>\n",
       "    </table>\n",
       "</body>\n",
       "</html>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "cr = om.CaseReader(prob.get_outputs_dir() / 'case_reader.sql')\n",
    "\n",
    "# get the last driver case\n",
    "driver_cases = cr.list_cases('driver')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "154be925",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:46:04.467257Z",
     "iopub.status.busy": "2026-10-02T14:46:04.467108Z",
     "iopub.status.idle": "2026-10-02T14:46:04.471348Z",
     "shell.execute_reply": "2026-10-02T14:46:04.470598Z"
    },
    "papermill": {
     "duration": 0.008771,
     "end_time": "2026-10-02T14:46:04.472004+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:04.463233+00:00",
     "status": "completed"
    },
    "scrolled": true,
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " driver - rank0:ScipyOptimize_SLSQP|9 ['con1', 'con2', 'obj', 'x', 'z']\n",
      "   root - _solve_nonlinear|9 ['con1', 'con2', 'obj', 'x', 'y1', 'y2', 'z']\n",
      "     root.nonlinear_solver - _solve_nonlinear|9|NLRunOnce|0 ['con1', 'con2', 'obj', 'x', 'y1', 'y2', 'z']\n"
     ]
    }
   ],
   "source": [
    "# get a recursive dict of child cases of the last driver case\n",
    "last_driver_case = driver_cases[-1]\n",
    "cases = cr.get_cases(last_driver_case, recurse=True, flat=False)\n",
    "\n",
    "# display selected information from nested dict of cases\n",
    "def print_cases(cases, indent=0):\n",
    "    for case, children in cases.items():\n",
    "        print(indent*' ', case.source, '-', case.name.split('.')[-1], sorted(case.outputs))\n",
    "        if children:\n",
    "            print_cases(children, indent+2)\n",
    "\n",
    "print_cases(cases)"
   ]
  }
 ],
 "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": 9.114755,
   "end_time": "2026-10-02T14:46:05.195761+00:00",
   "environment_variables": {},
   "exception": null,
   "input_path": "/home/runner/work/OpenMDAO/OpenMDAO/openmdao/docs/openmdao_book/features/recording/case_reader.ipynb",
   "output_path": "/home/runner/work/OpenMDAO/OpenMDAO/openmdao/docs/_executed_book/features/recording/case_reader.ipynb",
   "parameters": {},
   "start_time": "2026-10-02T14:45:56.081006+00:00",
   "version": "2.7.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}