{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "5e7ff19f",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:44:27.062644Z",
     "iopub.status.busy": "2026-10-02T14:44:27.062470Z",
     "iopub.status.idle": "2026-10-02T14:44:27.066645Z",
     "shell.execute_reply": "2026-10-02T14:44:27.066063Z"
    },
    "papermill": {
     "duration": 0.006647,
     "end_time": "2026-10-02T14:44:27.067224+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:44:27.060577+00:00",
     "status": "completed"
    },
    "tags": [
     "remove-input",
     "active-ipynb",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "try:\n",
    "    from openmdao.utils.notebook_utils import notebook_mode  # noqa: F401\n",
    "except ImportError:\n",
    "    !python -m pip install openmdao[notebooks]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "04dea126",
   "metadata": {
    "papermill": {
     "duration": 0.078332,
     "end_time": "2026-10-02T14:44:27.146581+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:44:27.068249+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "# Solver Debug Printing\n",
    "\n",
    "When working with a model and you have a situation where a nonlinear solver is not converging, it may be helpful to know the complete set of input and output values from the initialization of the failing case so that it can be recreated for debugging purposes. `NonlinearSolver` provides the `debug_print` option for this purpose:\n",
    "\n",
    "\n",
    "## NonlinearSolver Options"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "ac35ede8",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:44:27.155006Z",
     "iopub.status.busy": "2026-10-02T14:44:27.154823Z",
     "iopub.status.idle": "2026-10-02T14:44:28.380075Z",
     "shell.execute_reply": "2026-10-02T14:44:28.379400Z"
    },
    "papermill": {
     "duration": 1.227649,
     "end_time": "2026-10-02T14:44:28.380686+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:44:27.153037+00:00",
     "status": "completed"
    },
    "tags": [
     "remove-input"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "<!DOCTYPE html>\n",
       "<html lang=\"en\">\n",
       "<head>\n",
       "    <style>\n",
       "        h2 {\n",
       "            text-align: center;\n",
       "        }\n",
       "    </style>\n",
       "</head>\n",
       "<body>\n",
       "    <h2></h2>\n",
       "        <table style=\"border: 1px solid #999; border-collapse: collapse;\">\n",
       "        <tr><th style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; background-color: #E9E9E9; text-align: left;\">Option</th><th style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; background-color: #E9E9E9; text-align: left;\">Default</th><th style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; background-color: #E9E9E9; text-align: left;\">Acceptable Values</th><th style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; background-color: #E9E9E9; text-align: left;\">Acceptable Types</th><th style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; background-color: #E9E9E9; text-align: left;\">Description</th></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">atol</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">1e-10</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">N/A</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">N/A</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">absolute error tolerance</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">debug_print</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;\">If True, the values of input and output variables at the start of iteration are printed and written to a file after a failure to converge or when encountering aninvalid value in the residual.</td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">err_on_non_converge</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">False</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">[True, False]</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">[&#x27;bool&#x27;]</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">When True, AnalysisError will be raised if we don&#x27;t converge.</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">iprint</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">1</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">N/A</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">[&#x27;int&#x27;]</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">whether to print output</td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">maxiter</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">10</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">N/A</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">[&#x27;int&#x27;]</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">maximum number of iterations</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">restart_from_successful</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;\">If True, the states are cached after a successful solve and used to restart the solver in the case of a failed solve.</td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rtol</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">1e-10</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">N/A</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">N/A</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">relative error tolerance</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">stall_limit</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">0</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">N/A</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">N/A</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">Number of iterations after which, if the residual norms are identical within the stall_tol, then terminate as if max iterations were reached. Default is 0, which disables this feature.</td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">stall_tol</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">1e-12</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">N/A</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">N/A</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">When stall checking is enabled, the threshold below which the residual norm is considered unchanged.</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">stall_tol_type</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rel</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">[&#x27;abs&#x27;, &#x27;rel&#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;\">Specifies whether the absolute or relative norm of the residual is used for stall detection.</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.NonlinearSolver\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b4ddfb87",
   "metadata": {
    "papermill": {
     "duration": 0.036966,
     "end_time": "2026-10-02T14:44:28.419344+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:44:28.382378+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "## Usage\n",
    "\n",
    "This example shows how to use the `debug_print` option for a `NonlinearSolver`. When this option is set to True, the values of the input and output variables will be displayed and written to a file if the solver fails to converge."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "1890802d",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:44:28.423679Z",
     "iopub.status.busy": "2026-10-02T14:44:28.423214Z",
     "iopub.status.idle": "2026-10-02T14:44:29.326496Z",
     "shell.execute_reply": "2026-10-02T14:44:29.325910Z"
    },
    "papermill": {
     "duration": 0.906492,
     "end_time": "2026-10-02T14:44:29.327303+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:44:28.420811+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\">Circuit</span><span class=\"p\">(</span><span class=\"n\">om</span><span class=\"o\">.</span><span class=\"n\">Group</span><span class=\"p\">):</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;n1&#39;</span><span class=\"p\">,</span> <span class=\"n\">Node</span><span class=\"p\">(</span><span class=\"n\">n_in</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">n_out</span><span class=\"o\">=</span><span class=\"mi\">2</span><span class=\"p\">),</span> <span class=\"n\">promotes_inputs</span><span class=\"o\">=</span><span class=\"p\">[(</span><span class=\"s1\">&#39;I_in:0&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;I_in&#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;n2&#39;</span><span class=\"p\">,</span> <span class=\"n\">Node</span><span class=\"p\">())</span>  <span class=\"c1\"># leaving defaults</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;R1&#39;</span><span class=\"p\">,</span> <span class=\"n\">Resistor</span><span class=\"p\">(</span><span class=\"n\">R</span><span class=\"o\">=</span><span class=\"mf\">100.</span><span class=\"p\">),</span> <span class=\"n\">promotes_inputs</span><span class=\"o\">=</span><span class=\"p\">[(</span><span class=\"s1\">&#39;V_out&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;Vg&#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;R2&#39;</span><span class=\"p\">,</span> <span class=\"n\">Resistor</span><span class=\"p\">(</span><span class=\"n\">R</span><span class=\"o\">=</span><span class=\"mf\">10000.</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\">Diode</span><span class=\"p\">(),</span> <span class=\"n\">promotes_inputs</span><span class=\"o\">=</span><span class=\"p\">[(</span><span class=\"s1\">&#39;V_out&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;Vg&#39;</span><span class=\"p\">)])</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">connect</span><span class=\"p\">(</span><span class=\"s1\">&#39;n1.V&#39;</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"s1\">&#39;R1.V_in&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;R2.V_in&#39;</span><span class=\"p\">])</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">connect</span><span class=\"p\">(</span><span class=\"s1\">&#39;R1.I&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;n1.I_out:0&#39;</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">connect</span><span class=\"p\">(</span><span class=\"s1\">&#39;R2.I&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;n1.I_out:1&#39;</span><span class=\"p\">)</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">connect</span><span class=\"p\">(</span><span class=\"s1\">&#39;n2.V&#39;</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"s1\">&#39;R2.V_out&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;D1.V_in&#39;</span><span class=\"p\">])</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">connect</span><span class=\"p\">(</span><span class=\"s1\">&#39;R2.I&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;n2.I_in:0&#39;</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">connect</span><span class=\"p\">(</span><span class=\"s1\">&#39;D1.I&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;n2.I_out:0&#39;</span><span class=\"p\">)</span>\n\n        <span class=\"bp\">self</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\">NewtonSolver</span><span class=\"p\">(</span><span class=\"n\">solve_subsystems</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">nonlinear_solver</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"p\">[</span><span class=\"s1\">&#39;iprint&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"mi\">2</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">nonlinear_solver</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"p\">[</span><span class=\"s1\">&#39;maxiter&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"mi\">20</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">linear_solver</span> <span class=\"o\">=</span> <span class=\"n\">om</span><span class=\"o\">.</span><span class=\"n\">DirectSolver</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}{Circuit}\\PY{p}{(}\\PY{n}{om}\\PY{o}{.}\\PY{n}{Group}\\PY{p}{)}\\PY{p}{:}\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}{n1}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{Node}\\PY{p}{(}\\PY{n}{n\\PYZus{}in}\\PY{o}{=}\\PY{l+m+mi}{1}\\PY{p}{,} \\PY{n}{n\\PYZus{}out}\\PY{o}{=}\\PY{l+m+mi}{2}\\PY{p}{)}\\PY{p}{,} \\PY{n}{promotes\\PYZus{}inputs}\\PY{o}{=}\\PY{p}{[}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{I\\PYZus{}in:0}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{I\\PYZus{}in}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{)}\\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}{n2}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{Node}\\PY{p}{(}\\PY{p}{)}\\PY{p}{)}  \\PY{c+c1}{\\PYZsh{} leaving defaults}\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}{R1}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{Resistor}\\PY{p}{(}\\PY{n}{R}\\PY{o}{=}\\PY{l+m+mf}{100.}\\PY{p}{)}\\PY{p}{,} \\PY{n}{promotes\\PYZus{}inputs}\\PY{o}{=}\\PY{p}{[}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{V\\PYZus{}out}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{Vg}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{)}\\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}{R2}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{Resistor}\\PY{p}{(}\\PY{n}{R}\\PY{o}{=}\\PY{l+m+mf}{10000.}\\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}{Diode}\\PY{p}{(}\\PY{p}{)}\\PY{p}{,} \\PY{n}{promotes\\PYZus{}inputs}\\PY{o}{=}\\PY{p}{[}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{V\\PYZus{}out}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{Vg}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{)}\\PY{p}{]}\\PY{p}{)}\n\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{connect}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{n1.V}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{R1.V\\PYZus{}in}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{R2.V\\PYZus{}in}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\\PY{p}{)}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{connect}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{R1.I}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{n1.I\\PYZus{}out:0}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{)}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{connect}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{R2.I}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{n1.I\\PYZus{}out:1}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{)}\n\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{connect}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{n2.V}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{R2.V\\PYZus{}out}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{D1.V\\PYZus{}in}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\\PY{p}{)}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{connect}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{R2.I}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{n2.I\\PYZus{}in:0}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{)}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{connect}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{D1.I}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{n2.I\\PYZus{}out:0}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{)}\n\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{nonlinear\\PYZus{}solver} \\PY{o}{=} \\PY{n}{om}\\PY{o}{.}\\PY{n}{NewtonSolver}\\PY{p}{(}\\PY{n}{solve\\PYZus{}subsystems}\\PY{o}{=}\\PY{k+kc}{False}\\PY{p}{)}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{nonlinear\\PYZus{}solver}\\PY{o}{.}\\PY{n}{options}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{iprint}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]} \\PY{o}{=} \\PY{l+m+mi}{2}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{nonlinear\\PYZus{}solver}\\PY{o}{.}\\PY{n}{options}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{maxiter}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]} \\PY{o}{=} \\PY{l+m+mi}{20}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{linear\\PYZus{}solver} \\PY{o}{=} \\PY{n}{om}\\PY{o}{.}\\PY{n}{DirectSolver}\\PY{p}{(}\\PY{p}{)}\n\\end{Verbatim}\n",
      "application/papermill.record/text/plain": "class Circuit(om.Group):\n\n    def setup(self):\n        self.add_subsystem('n1', Node(n_in=1, n_out=2), promotes_inputs=[('I_in:0', 'I_in')])\n        self.add_subsystem('n2', Node())  # leaving defaults\n\n        self.add_subsystem('R1', Resistor(R=100.), promotes_inputs=[('V_out', 'Vg')])\n        self.add_subsystem('R2', Resistor(R=10000.))\n        self.add_subsystem('D1', Diode(), promotes_inputs=[('V_out', 'Vg')])\n\n        self.connect('n1.V', ['R1.V_in', 'R2.V_in'])\n        self.connect('R1.I', 'n1.I_out:0')\n        self.connect('R2.I', 'n1.I_out:1')\n\n        self.connect('n2.V', ['R2.V_out', 'D1.V_in'])\n        self.connect('R2.I', 'n2.I_in:0')\n        self.connect('D1.I', 'n2.I_out:0')\n\n        self.nonlinear_solver = om.NewtonSolver(solve_subsystems=False)\n        self.nonlinear_solver.options['iprint'] = 2\n        self.nonlinear_solver.options['maxiter'] = 20\n        self.linear_solver = om.DirectSolver()"
     },
     "metadata": {
      "scrapbook": {
       "mime_prefix": "application/papermill.record/",
       "name": "code_src67"
      }
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "from openmdao.utils.notebook_utils import get_code\n",
    "from myst_nb import glue\n",
    "glue(\"code_src67\", get_code(\"openmdao.test_suite.scripts.circuit_analysis.Circuit\"), display=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dcdea7bb",
   "metadata": {
    "papermill": {
     "duration": 0.00708,
     "end_time": "2026-10-02T14:44:29.335645+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:44:29.328565+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    ":::{dropdown} `Circuit` class definition \n",
    "\n",
    "{glue:}`code_src67`\n",
    ":::"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "f2991397",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:44:29.338795Z",
     "iopub.status.busy": "2026-10-02T14:44:29.338607Z",
     "iopub.status.idle": "2026-10-02T14:44:30.605301Z",
     "shell.execute_reply": "2026-10-02T14:44:30.604780Z"
    },
    "papermill": {
     "duration": 1.269468,
     "end_time": "2026-10-02T14:44:30.606136+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:44:29.336668+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1790952270.574991] [runnervm8df0l:8552 :0]        ib_iface.c:1269 UCX  ERROR mana_0: iface 0x564a8c047eb0 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",
      "[1790952270.575257] [runnervm8df0l:8552 :0]      ucp_worker.c:1412 UCX  ERROR uct_iface_open(ud_verbs/mana_0:1) failed: Input/output error\n",
      "\n",
      "=======\n",
      "circuit\n",
      "=======\n",
      "NL: Newton 0 ; 2.53337743 1\n",
      "NL: Newton 1 ; 6.9707252e+152 2.75155416e+152\n",
      "NL: Newton 2 ; 2.56438649e+152 1.01224021e+152\n",
      "NL: Newton 3 ; 9.43385069e+151 3.72382361e+151\n",
      "NL: Newton 4 ; 3.47051972e+151 1.36991815e+151\n",
      "NL: Newton 5 ; 1.27673286e+151 5.03964723e+150\n",
      "NL: Newton 6 ; 4.69683769e+150 1.85398261e+150\n",
      "NL: Newton 7 ; 1.72787003e+150 6.82042086e+149\n",
      "NL: Newton 8 ; 6.35647859e+149 2.50909261e+149\n",
      "NL: Newton 9 ; 2.33841779e+149 9.23043588e+148\n",
      "NL: Newton 10 ; 8.60255831e+148 3.39568759e+148\n",
      "NL: NewtonSolver 'NL: Newton' on system 'circuit' failed to converge in 10 iterations.\n",
      "\n",
      "# Inputs and outputs at start of iteration 'rank0:root._solve_nonlinear|0|NLRunOnce|0|circuit._solve_nonlinear|0':\n",
      "\n",
      "# nonlinear inputs\n",
      "{'circuit.D1.V_in': array([ 0.001+0.j]),\n",
      " 'circuit.D1.V_out': array([ 0.+0.j]),\n",
      " 'circuit.R1.V_in': array([ 10.+0.j]),\n",
      " 'circuit.R1.V_out': array([ 0.+0.j]),\n",
      " 'circuit.R2.V_in': array([ 10.+0.j]),\n",
      " 'circuit.R2.V_out': array([ 0.001+0.j]),\n",
      " 'circuit.n1.I_in:0': array([ 0.1+0.j]),\n",
      " 'circuit.n1.I_out:0': array([ 1.+0.j]),\n",
      " 'circuit.n1.I_out:1': array([ 1.+0.j]),\n",
      " 'circuit.n2.I_in:0': array([ 1.+0.j]),\n",
      " 'circuit.n2.I_out:0': array([ 1.+0.j])}\n",
      "\n",
      "# nonlinear outputs\n",
      "{'circuit.D1.I': array([ 1.+0.j]),\n",
      " 'circuit.R1.I': array([ 1.+0.j]),\n",
      " 'circuit.R2.I': array([ 1.+0.j]),\n",
      " 'circuit.n1.V': array([ 10.+0.j]),\n",
      " 'circuit.n2.V': array([ 0.001+0.j])}\n",
      "\n",
      "Inputs and outputs at start of iteration have been saved to 'solver_errors.0.out'.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "# Inputs and outputs at start of iteration 'rank0:root._solve_nonlinear|0|NLRunOnce|0|circuit._solve_nonlinear|0':\n",
      "\n",
      "# nonlinear inputs\n",
      "{'circuit.D1.V_in': array([ 0.001+0.j]),\n",
      " 'circuit.D1.V_out': array([ 0.+0.j]),\n",
      " 'circuit.R1.V_in': array([ 10.+0.j]),\n",
      " 'circuit.R1.V_out': array([ 0.+0.j]),\n",
      " 'circuit.R2.V_in': array([ 10.+0.j]),\n",
      " 'circuit.R2.V_out': array([ 0.001+0.j]),\n",
      " 'circuit.n1.I_in:0': array([ 0.1+0.j]),\n",
      " 'circuit.n1.I_out:0': array([ 1.+0.j]),\n",
      " 'circuit.n1.I_out:1': array([ 1.+0.j]),\n",
      " 'circuit.n2.I_in:0': array([ 1.+0.j]),\n",
      " 'circuit.n2.I_out:0': array([ 1.+0.j])}\n",
      "\n",
      "# nonlinear outputs\n",
      "{'circuit.D1.I': array([ 1.+0.j]),\n",
      " 'circuit.R1.I': array([ 1.+0.j]),\n",
      " 'circuit.R2.I': array([ 1.+0.j]),\n",
      " 'circuit.n1.V': array([ 10.+0.j]),\n",
      " 'circuit.n2.V': array([ 0.001+0.j])}\n",
      "\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[runnervm8df0l:08552] pml_ucx.c:313  Error: Failed to create UCP worker\n"
     ]
    }
   ],
   "source": [
    "from packaging.version import Version\n",
    "import numpy as np\n",
    "\n",
    "import openmdao.api as om\n",
    "from openmdao.test_suite.scripts.circuit_analysis import Circuit\n",
    "from openmdao.utils.general_utils import printoptions\n",
    "\n",
    "p = om.Problem()\n",
    "model = p.model\n",
    "\n",
    "model.add_subsystem('circuit', Circuit())\n",
    "\n",
    "p.setup()\n",
    "\n",
    "nl = model.circuit.nonlinear_solver = om.NewtonSolver(solve_subsystems=False)\n",
    "\n",
    "nl.options['iprint'] = 2\n",
    "nl.options['debug_print'] = True\n",
    "nl.options['err_on_non_converge'] = True\n",
    "\n",
    "# set some poor initial guesses so that we don't converge\n",
    "p.set_val('circuit.I_in', 0.1, units='A')\n",
    "p.set_val('circuit.Vg', 0.0, units='V')\n",
    "p.set_val('circuit.n1.V', 10.)\n",
    "p.set_val('circuit.n2.V', 1e-3)\n",
    "\n",
    "opts = {}\n",
    "# formatting has changed in numpy 1.14 and beyond.\n",
    "if Version(np.__version__) >= Version(\"1.14\"):\n",
    "    opts[\"legacy\"] = '1.13'\n",
    "\n",
    "with printoptions(**opts):\n",
    "    # run the model\n",
    "    try:\n",
    "        p.run_model()\n",
    "    except om.AnalysisError:\n",
    "        pass\n",
    "\n",
    "with open('solver_errors.0.out', 'r') as f:\n",
    "    print(f.read())"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "55f7d283",
   "metadata": {
    "papermill": {
     "duration": 0.001557,
     "end_time": "2026-10-02T14:44:30.609438+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:44:30.607881+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "In larger models, OpenMDAO makes it easier to set the `debug_print` option on `set_solver_print` method on the Problem or System.\n",
    "To leave the print level of the solver unchanged, but enable debug printing, one can call `set_solver_print(level=None, debug_print=True)`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "e9b6fb7d",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:44:30.613333Z",
     "iopub.status.busy": "2026-10-02T14:44:30.613145Z",
     "iopub.status.idle": "2026-10-02T14:44:30.636307Z",
     "shell.execute_reply": "2026-10-02T14:44:30.635632Z"
    },
    "papermill": {
     "duration": 0.02612,
     "end_time": "2026-10-02T14:44:30.637088+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:44:30.610968+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "=======\n",
      "circuit\n",
      "=======\n",
      "NL: Newton 0 ; 2.53337743 1\n",
      "NL: Newton 1 ; 6.9707252e+152 2.75155416e+152\n",
      "NL: Newton 2 ; 2.56438649e+152 1.01224021e+152\n",
      "NL: Newton 3 ; 9.43385069e+151 3.72382361e+151\n",
      "NL: Newton 4 ; 3.47051972e+151 1.36991815e+151\n",
      "NL: Newton 5 ; 1.27673286e+151 5.03964723e+150\n",
      "NL: Newton 6 ; 4.69683769e+150 1.85398261e+150\n",
      "NL: Newton 7 ; 1.72787003e+150 6.82042086e+149\n",
      "NL: Newton 8 ; 6.35647859e+149 2.50909261e+149\n",
      "NL: Newton 9 ; 2.33841779e+149 9.23043588e+148\n",
      "NL: Newton 10 ; 8.60255831e+148 3.39568759e+148\n",
      "NL: NewtonSolver 'NL: Newton' on system 'circuit' failed to converge in 10 iterations.\n",
      "\n",
      "# Inputs and outputs at start of iteration 'rank0:root._solve_nonlinear|0|NLRunOnce|0|circuit._solve_nonlinear|0':\n",
      "\n",
      "# nonlinear inputs\n",
      "{'circuit.D1.V_in': array([ 0.001+0.j]),\n",
      " 'circuit.D1.V_out': array([ 0.+0.j]),\n",
      " 'circuit.R1.V_in': array([ 10.+0.j]),\n",
      " 'circuit.R1.V_out': array([ 0.+0.j]),\n",
      " 'circuit.R2.V_in': array([ 10.+0.j]),\n",
      " 'circuit.R2.V_out': array([ 0.001+0.j]),\n",
      " 'circuit.n1.I_in:0': array([ 0.1+0.j]),\n",
      " 'circuit.n1.I_out:0': array([ 1.+0.j]),\n",
      " 'circuit.n1.I_out:1': array([ 1.+0.j]),\n",
      " 'circuit.n2.I_in:0': array([ 1.+0.j]),\n",
      " 'circuit.n2.I_out:0': array([ 1.+0.j])}\n",
      "\n",
      "# nonlinear outputs\n",
      "{'circuit.D1.I': array([ 1.+0.j]),\n",
      " 'circuit.R1.I': array([ 1.+0.j]),\n",
      " 'circuit.R2.I': array([ 1.+0.j]),\n",
      " 'circuit.n1.V': array([ 10.+0.j]),\n",
      " 'circuit.n2.V': array([ 0.001+0.j])}\n",
      "\n",
      "Inputs and outputs at start of iteration have been saved to 'solver_errors.0.out'.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "# Inputs and outputs at start of iteration 'rank0:root._solve_nonlinear|0|NLRunOnce|0|circuit._solve_nonlinear|0':\n",
      "\n",
      "# nonlinear inputs\n",
      "{'circuit.D1.V_in': array([ 0.001+0.j]),\n",
      " 'circuit.D1.V_out': array([ 0.+0.j]),\n",
      " 'circuit.R1.V_in': array([ 10.+0.j]),\n",
      " 'circuit.R1.V_out': array([ 0.+0.j]),\n",
      " 'circuit.R2.V_in': array([ 10.+0.j]),\n",
      " 'circuit.R2.V_out': array([ 0.001+0.j]),\n",
      " 'circuit.n1.I_in:0': array([ 0.1+0.j]),\n",
      " 'circuit.n1.I_out:0': array([ 1.+0.j]),\n",
      " 'circuit.n1.I_out:1': array([ 1.+0.j]),\n",
      " 'circuit.n2.I_in:0': array([ 1.+0.j]),\n",
      " 'circuit.n2.I_out:0': array([ 1.+0.j])}\n",
      "\n",
      "# nonlinear outputs\n",
      "{'circuit.D1.I': array([ 1.+0.j]),\n",
      " 'circuit.R1.I': array([ 1.+0.j]),\n",
      " 'circuit.R2.I': array([ 1.+0.j]),\n",
      " 'circuit.n1.V': array([ 10.+0.j]),\n",
      " 'circuit.n2.V': array([ 0.001+0.j])}\n",
      "\n"
     ]
    }
   ],
   "source": [
    "from packaging.version import Version\n",
    "import numpy as np\n",
    "\n",
    "import openmdao.api as om\n",
    "from openmdao.test_suite.scripts.circuit_analysis import Circuit\n",
    "from openmdao.utils.general_utils import printoptions\n",
    "\n",
    "p = om.Problem()\n",
    "model = p.model\n",
    "\n",
    "model.add_subsystem('circuit', Circuit())\n",
    "\n",
    "p.setup()\n",
    "\n",
    "nl = model.circuit.nonlinear_solver = om.NewtonSolver(solve_subsystems=False, err_on_non_converge=True)\n",
    "\n",
    "p.set_solver_print(level=2, debug_print=True)\n",
    "\n",
    "# set some poor initial guesses so that we don't converge\n",
    "p.set_val('circuit.I_in', 0.1, units='A')\n",
    "p.set_val('circuit.Vg', 0.0, units='V')\n",
    "p.set_val('circuit.n1.V', 10.)\n",
    "p.set_val('circuit.n2.V', 1e-3)\n",
    "\n",
    "opts = {}\n",
    "# formatting has changed in numpy 1.14 and beyond.\n",
    "if Version(np.__version__) >= Version(\"1.14\"):\n",
    "    opts[\"legacy\"] = '1.13'\n",
    "\n",
    "with printoptions(**opts):\n",
    "    # run the model\n",
    "    try:\n",
    "        p.run_model()\n",
    "    except om.AnalysisError:\n",
    "        pass\n",
    "\n",
    "with open('solver_errors.0.out', 'r') as f:\n",
    "    print(f.read())"
   ]
  }
 ],
 "metadata": {
  "celltoolbar": "Tags",
  "kernelspec": {
   "display_name": "py312",
   "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.124423,
   "end_time": "2026-10-02T14:44:31.455415+00:00",
   "environment_variables": {},
   "exception": null,
   "input_path": "/home/runner/work/OpenMDAO/OpenMDAO/openmdao/docs/openmdao_book/features/debugging/debugging_solvers.ipynb",
   "output_path": "/home/runner/work/OpenMDAO/OpenMDAO/openmdao/docs/_executed_book/features/debugging/debugging_solvers.ipynb",
   "parameters": {},
   "start_time": "2026-10-02T14:44:26.330992+00:00",
   "version": "2.7.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}