{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "fac40381",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:46:52.869520Z",
     "iopub.status.busy": "2026-10-02T14:46:52.869314Z",
     "iopub.status.idle": "2026-10-02T14:46:52.873152Z",
     "shell.execute_reply": "2026-10-02T14:46:52.872732Z"
    },
    "papermill": {
     "duration": 0.007029,
     "end_time": "2026-10-02T14:46:52.873993+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:52.866964+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": "566005fb",
   "metadata": {
    "papermill": {
     "duration": 0.001141,
     "end_time": "2026-10-02T14:46:52.876580+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:52.875439+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "# OpenMDAO Docs Style Guide\n",
    "\n",
    "This document outlines OpenMDAO-v3 documentation conventions regarding\n",
    "both content and formatting.\n",
    "\n",
    "\n",
    "## General Docstring Conventions\n",
    "\n",
    "General docstring rules:\n",
    "\n",
    "- All docstrings should begin and end with triple double quotes (\"\"\").\n",
    "- Modules, classes, methods, and functions must have docstrings\n",
    "  whether the object is public or private.\n",
    "\n",
    "Two types of docstrings:\n",
    "\n",
    "1. One-line docstrings:\n",
    "\n",
    "```\n",
    "     \"\"\"Do something.\"\"\"\n",
    "```\n",
    "\n",
    "   - Phrase or sentence ended by a period.\n",
    "   - No empty space between the text and the triple double quotes.\n",
    "\n",
    "2. Multi-line docstrings:\n",
    "```\n",
    "     \"\"\"Summary line.\n",
    "\n",
    "     Paragraph 1.\n",
    "     \"\"\"\n",
    "```\n",
    "\n",
    "   - Summary line ended by a period.\n",
    "   - No empty space between the summary line and\n",
    "     the opening triple double quotes.\n",
    "   - Paragraphs separated by blank lines.\n",
    "   - Can contain a list of attributes/args/returns, explained below.\n",
    "   - No empty line at the end, before closing triple double quotes.\n",
    "\n",
    "Detailed docstring rules:\n",
    "\n",
    "1. Modules:\n",
    "\n",
    "   - Either one-line or multi-line.\n",
    "   - No blank line after the docstring.\n",
    "   - List the classes and functions inside (this can be automated).\n",
    "\n",
    "2. Classes:\n",
    "\n",
    "   - Either one-line or multi-line.\n",
    "   - List the attributes, if any (then must be multi-line).\n",
    "   - Blank line after the docstring.\n",
    "\n",
    "```\n",
    "     \"\"\"Summary line.\n",
    "\n",
    "     Paragraph 1.\n",
    "\n",
    "     Attributes\n",
    "     ----------\n",
    "     attribute_name : Type\n",
    "         description ending with a period.\n",
    "     \"\"\"\n",
    "```\n",
    "\n",
    "3. Methods or functions:\n",
    "\n",
    "   - Either one-line or multi-line.\n",
    "   - List the arguments (except for self) and the returned variables, if any.\n",
    "   - The summary line/one-line docstring should be an imperative sentence,\n",
    "     not a descriptive phrase:\n",
    "\n",
    "     - Incorrect: `\"\"\"Does something.\"\"\"`\n",
    "\n",
    "     - Correct: `\"\"\"Do something.\"\"\"`\n",
    "\n",
    "   - No blank line after the docstring.\n",
    "\n",
    "```\n",
    "     \"\"\"Do something.\n",
    "\n",
    "     Paragraph 1.\n",
    "\n",
    "     Parameters\n",
    "     ----------\n",
    "     argument_name : Type\n",
    "         description ending with a period.\n",
    "\n",
    "     Returns\n",
    "     -------\n",
    "     Type\n",
    "         description ending with a period.\n",
    "     \"\"\"\n",
    "```\n",
    "\n",
    "   - Sphinx does not correctly handle decorated methods. To ensure a method's\n",
    "     call signature appears correctly in the docs, put the call signature of the method\n",
    "     into the first line of the docstring. [See Sphinx and Decorated Methods](sphinx_decorators.ipynb) for more information.) For example:\n",
    "\n",
    "```\n",
    "     \"\"\"\n",
    "     method_name(self, arg1, arg2)\n",
    "     Do something.\n",
    "\n",
    "     Paragraph 1.\n",
    "\n",
    "     Parameters\n",
    "     ----------\n",
    "     argument_name : Type\n",
    "         description ending with a period.\n",
    "\n",
    "     Returns\n",
    "     -------\n",
    "     Type\n",
    "         description ending with a period.\n",
    "     \"\"\"\n",
    "```\n",
    "\n",
    "## Notebook Guidelines\n",
    "\n",
    "1. Each notebook should include this block at the top to import OpenMDAO if not already available.  This is necessary on the cloud-based notebook environments like Colab.\n",
    "\n",
    "```\n",
    "try:\n",
    "    import openmdao.api as om\n",
    "except ImportError:\n",
    "    !python -m pip install openmdao[notebooks]\n",
    "    import openmdao.api as om\n",
    "```\n",
    "\n",
    "This cell should be tagged with the following metadata.  The \"remove-input\" and \"remove-output\" tags prevent it from showing up in the documentation, and the \"hide_input\" portion collapses the input cell. To add tags in Jupyter Notebook, navigate to `View` -> `Cell Toolbar` -> `Tags`.\n",
    "\n",
    "```\n",
    "{\n",
    "  \"hide_input\": true,\n",
    "  \"tags\": [\n",
    "    \"remove-input\",\n",
    "    \"remove-output\"\n",
    "  ],\n",
    "  \"trusted\": true\n",
    "}\n",
    "```\n",
    "\n",
    "2\\. Executed code in notebooks should be tested using the same assertions used in unittests.\n",
    "\n",
    "For instance, in the paraboloid case we have:\n",
    "\n",
    "```\n",
    "# This code block is hidden by default.\n",
    "# It exists to verify that the above code works correctly.\n",
    "\n",
    "from openmdao.utils.assert_utils import assert_near_equal\n",
    "\n",
    "# minimum value\n",
    "assert_near_equal(prob.get_val('paraboloid.f'), -27.33333, 1e-6);\n",
    "\n",
    "# location of the minimum\n",
    "assert_near_equal(prob.get_val('paraboloid.x'), 6.6667, 1e-4);\n",
    "assert_near_equal(prob.get_val('paraboloid.y'), -7.33333, 1e-4);\n",
    "```\n",
    "\n",
    "It's not necessary to show this in the documentation, so remove it using the same\n",
    "hiding metadata above.\n",
    "\n",
    "3. A pre-commit hook checks that all notebook output cells are clean before committing. Run `jupyter nbconvert --clear-output --inplace <notebook.ipynb>` to clear outputs, or use the `reset_notebook` command installed with OpenMDAO's dev tools.\n",
    "\n",
    "4. Since 'n2.html' files and other build artifacts need to be manually copied over to the output `_build` directory to make the docs, each example notebook should be kept in its own directory.\n",
    "\n",
    "\n",
    "## Notebook Metadata Reference\n",
    "\n",
    "### Cell-level tags\n",
    "\n",
    "Cell tags are set in the cell metadata under `\"tags\"`. In Jupyter Notebook, navigate to `View` -> `Cell Toolbar` -> `Tags` to add them.\n",
    "\n",
    "| Tag | Effect |\n",
    "|-----|--------|\n",
    "| `remove-input` | Hides the cell's source code in the rendered docs. |\n",
    "| `remove-output` | Hides all output from the cell in the rendered docs. |\n",
    "| `remove-cell` | Removes the entire cell (input and output) from the rendered docs. |\n",
    "| `hide-input` | Collapses the cell's source into a toggle; output is still visible. |\n",
    "| `hide-output` | Collapses the cell's output into a toggle; source is still visible. |\n",
    "| `active-ipynb` | Marks a cell as active only when running interactively (e.g. Colab install cells). The doc build skips these cells. |\n",
    "| `allow-assert` | Suppresses the pre-commit check that flags visible assert statements. Use when an assert must appear in the rendered output. |\n",
    "| `output_scroll` | Renders the cell output in a scrollable box. |\n",
    "\n",
    "### Notebook-level metadata\n",
    "\n",
    "Notebook-level metadata is set in the top-level `\"metadata\"` dict of the `.ipynb` file (not inside any individual cell). These keys are read by the doc build system.\n",
    "\n",
    "| Key | Value | Effect |\n",
    "|-----|-------|--------|\n",
    "| `\"mpi\"` | `true` | Marks the notebook as requiring MPI. The build system executes it serially (outside the parallel pool) since it internally manages its own `mpiexec` subprocesses via `mpi_exec()`. |\n",
    "| `\"reports\"` | `true` | Executes the notebook with `OPENMDAO_REPORTS=1`, enabling the OpenMDAO HTML reports system. Use this only for notebooks that explicitly demonstrate the reports feature. All other notebooks run with reports disabled to avoid overhead. |\n",
    "| `\"orphan\"` | `true` | Tells Sphinx not to warn about this notebook being absent from any `toctree`. Used for index/landing-page notebooks that are included via other mechanisms. |\n",
    "\n",
    "\n",
    "## Notebook Guidelines for MPI Features\n",
    "\n",
    "For features that require MPI, use `mpi_exec()` from `openmdao.utils.notebook_utils` to run an MPI script written via `%%writefile`. This function:\n",
    "\n",
    "- Displays a note that the feature requires MPI and may not work on Colab or Binder.\n",
    "- Echoes the command being run.\n",
    "- Captures and prints stdout.\n",
    "- Raises `RuntimeError` if the script exits with a non-zero return code, so that doc build failures are caught.\n",
    "\n",
    "The typical pattern looks like this:\n",
    "\n",
    "```python\n",
    "%%writefile mpi_script_0.py\n",
    "import openmdao.api as om\n",
    "# ... model setup ...\n",
    "prob.run_model()\n",
    "```\n",
    "\n",
    "```python\n",
    "from openmdao.utils.notebook_utils import mpi_exec\n",
    "mpi_exec(4, 'mpi_script_0.py')\n",
    "```\n",
    "\n",
    "There is no need for a separate markdown warning cell — `mpi_exec` emits the MPI note automatically as part of its output.\n",
    "\n",
    "Also add `\"mpi\": true` to the notebook's top-level metadata so the build system knows to execute it outside the parallel worker pool.\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "## Collapsible Class Definition Blocks\n",
    "\n",
    "When a notebook uses a class from the OpenMDAO test suite or elsewhere, it is good\n",
    "practice to show the class definition in a collapsible block so users can inspect it\n",
    "without it cluttering the page. Use the `{dropdown}` directive from `sphinx-design`\n",
    "together with `glue` from `myst_nb`:\n",
    "\n",
    "```python\n",
    "from openmdao.utils.notebook_utils import get_code\n",
    "from myst_nb import glue\n",
    "glue(\"code_src\", get_code(\"openmdao.test_suite.components.paraboloid.Paraboloid\"), display=False)\n",
    "```\n",
    "\n",
    "```markdown\n",
    ":::{{dropdown}} `Paraboloid` class definition\n",
    "\n",
    "{{glue:}}`code_src`\n",
    ":::\n",
    "```\n",
    "\n",
    "The `glue` call must be executed by the kernel, so tag it `remove-input` and\n",
    "`remove-output` (not `remove-cell`) so it runs but does not appear in the rendered docs. The `{dropdown}` cell renders as a collapsed block with a\n",
    "toggle arrow. Do **not** use the older `{Admonition}` + `:class: dropdown` pattern,\n",
    "which was specific to sphinx-book-theme and does not render as collapsible in the\n",
    "current theme.\n",
    "\n",
    "## Building the Documentation\n",
    "\n",
    "See the [doc build guide](doc_build.ipynb) for instructions on building the documentation locally.\n",
    "\n",
    "\n",
    "## Embedding Autodocumentation Snippets into Documentation\n",
    "\n",
    "Sometimes in a feature doc, you want to reproduce a particular method or class or module right there within the text. The syntax to do this is provided by the sphinx.ext.autodoc module, in three commands, automodule, autoclass, and automethod. The syntax of these, inside of a markdown file or Jupyter cell is detailed in the following example code:"
   ]
  },
  {
   "cell_type": "raw",
   "id": "c8b36dae",
   "metadata": {
    "papermill": {
     "duration": 0.001082,
     "end_time": "2026-10-02T14:46:52.878920+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:52.877838+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "**AUTOMODULE EXAMPLE:**\n",
    "```{eval-rst}\n",
    "    .. automodule:: openmdao.core.group\n",
    "        :noindex:\n",
    "```\n",
    "\n",
    "**AUTOCLASS EXAMPLE:**\n",
    "```{eval-rst}\n",
    "    .. autoclass:: openmdao.core.group.Group\n",
    "        :noindex:\n",
    "```\n",
    "\n",
    "**AUTOMETHOD EXAMPLE:**\n",
    "```{eval-rst}\n",
    "  .. automethod:: openmdao.core.group.Group.add_subsystem\n",
    "      :noindex:\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "92d677af",
   "metadata": {
    "papermill": {
     "duration": 0.001086,
     "end_time": "2026-10-02T14:46:52.881323+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:52.880237+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "The :noindex: argument is needed to prevent unwanted replication interactions with the OpenMDAO source documentation. The above syntax will pull docstring info and produce the following output:\n",
    "\n",
    "## Adding a Link to a Document in a `.ipynb` File\n",
    "\n",
    "Sometimes in a document, you don't want or need to embed/display the entire\n",
    "document of a class to make your point. At these times, you want to just provide\n",
    "the user with an easy way to link to the autodoc for quick reference.\n",
    "\n",
    "We'll do this with a `[]()` link.  The basic syntax looks like this:\n",
    "```\n",
    "    You might find this [file](openmdao_book/path/to/file.ipynb) helpful.\n",
    "```\n",
    "This could be a link to a file or a link to a website like our [home page](https://openmdao.org)\n",
    "\n",
    "## Custom Functions for Embedding Items into OpenMDAO Documentation\n",
    "\n",
    "### `display_source`\n",
    "`om.display_source` is a custom function from OpenMDAO that takes one argument, which is a class, test, or method's full, dotted path (e.g. \"openmdao.core.tests.test_expl_comp.RectangleComp\").\n",
    "\n",
    "The syntax for invoking the function within a `.md` or `ipynb` file looks like this:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "0f156741",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:46:52.885343Z",
     "iopub.status.busy": "2026-10-02T14:46:52.885156Z",
     "iopub.status.idle": "2026-10-02T14:46:54.211264Z",
     "shell.execute_reply": "2026-10-02T14:46:54.210740Z"
    },
    "papermill": {
     "duration": 1.329151,
     "end_time": "2026-10-02T14:46:54.212214+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:52.883063+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<style>pre { line-height: 125%; }\n",
       "td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\n",
       "span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\n",
       "td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\n",
       "span.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\">RectangleComp</span><span class=\"p\">(</span><span class=\"n\">om</span><span class=\"o\">.</span><span class=\"n\">ExplicitComponent</span><span class=\"p\">):</span>\n",
       "<span class=\"w\">    </span><span class=\"sd\">&quot;&quot;&quot;</span>\n",
       "<span class=\"sd\">    A simple Explicit Component that computes the area of a rectangle.</span>\n",
       "<span class=\"sd\">    &quot;&quot;&quot;</span>\n",
       "\n",
       "    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">setup</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_input</span><span class=\"p\">(</span><span class=\"s1\">&#39;length&#39;</span><span class=\"p\">,</span> <span class=\"n\">val</span><span class=\"o\">=</span><span class=\"mf\">1.</span><span class=\"p\">)</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_input</span><span class=\"p\">(</span><span class=\"s1\">&#39;width&#39;</span><span class=\"p\">,</span> <span class=\"n\">val</span><span class=\"o\">=</span><span class=\"mf\">1.</span><span class=\"p\">)</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_output</span><span class=\"p\">(</span><span class=\"s1\">&#39;area&#39;</span><span class=\"p\">,</span> <span class=\"n\">val</span><span class=\"o\">=</span><span class=\"mf\">1.</span><span class=\"p\">)</span>\n",
       "\n",
       "    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">setup_partials</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">declare_partials</span><span class=\"p\">(</span><span class=\"s1\">&#39;*&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;*&#39;</span><span class=\"p\">)</span>\n",
       "\n",
       "    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">compute</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">inputs</span><span class=\"p\">,</span> <span class=\"n\">outputs</span><span class=\"p\">):</span>\n",
       "        <span class=\"n\">outputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;area&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">inputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;length&#39;</span><span class=\"p\">]</span> <span class=\"o\">*</span> <span class=\"n\">inputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;width&#39;</span><span class=\"p\">]</span>\n",
       "</pre></div>\n"
      ],
      "text/latex": [
       "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n",
       "\\PY{k}{class}\\PY{+w}{ }\\PY{n+nc}{RectangleComp}\\PY{p}{(}\\PY{n}{om}\\PY{o}{.}\\PY{n}{ExplicitComponent}\\PY{p}{)}\\PY{p}{:}\n",
       "\\PY{+w}{    }\\PY{l+s+sd}{\\PYZdq{}\\PYZdq{}\\PYZdq{}}\n",
       "\\PY{l+s+sd}{    A simple Explicit Component that computes the area of a rectangle.}\n",
       "\\PY{l+s+sd}{    \\PYZdq{}\\PYZdq{}\\PYZdq{}}\n",
       "\n",
       "    \\PY{k}{def}\\PY{+w}{ }\\PY{n+nf}{setup}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{p}{)}\\PY{p}{:}\n",
       "        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{add\\PYZus{}input}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{length}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{val}\\PY{o}{=}\\PY{l+m+mf}{1.}\\PY{p}{)}\n",
       "        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{add\\PYZus{}input}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{width}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{val}\\PY{o}{=}\\PY{l+m+mf}{1.}\\PY{p}{)}\n",
       "        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{add\\PYZus{}output}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{area}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{val}\\PY{o}{=}\\PY{l+m+mf}{1.}\\PY{p}{)}\n",
       "\n",
       "    \\PY{k}{def}\\PY{+w}{ }\\PY{n+nf}{setup\\PYZus{}partials}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{p}{)}\\PY{p}{:}\n",
       "        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{declare\\PYZus{}partials}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{*}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{*}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{)}\n",
       "\n",
       "    \\PY{k}{def}\\PY{+w}{ }\\PY{n+nf}{compute}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{p}{,} \\PY{n}{inputs}\\PY{p}{,} \\PY{n}{outputs}\\PY{p}{)}\\PY{p}{:}\n",
       "        \\PY{n}{outputs}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{area}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]} \\PY{o}{=} \\PY{n}{inputs}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{length}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]} \\PY{o}{*} \\PY{n}{inputs}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{width}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\n",
       "\\end{Verbatim}\n"
      ],
      "text/plain": [
       "class RectangleComp(om.ExplicitComponent):\n",
       "    \"\"\"\n",
       "    A simple Explicit Component that computes the area of a rectangle.\n",
       "    \"\"\"\n",
       "\n",
       "    def setup(self):\n",
       "        self.add_input('length', val=1.)\n",
       "        self.add_input('width', val=1.)\n",
       "        self.add_output('area', val=1.)\n",
       "\n",
       "    def setup_partials(self):\n",
       "        self.declare_partials('*', '*')\n",
       "\n",
       "    def compute(self, inputs, outputs):\n",
       "        outputs['area'] = inputs['length'] * inputs['width']"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import openmdao.api as om\n",
    "om.display_source(\"openmdao.core.tests.test_expl_comp.RectangleComp\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f3799194",
   "metadata": {
    "papermill": {
     "duration": 0.013214,
     "end_time": "2026-10-02T14:46:54.228853+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:54.215639+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "```{Note}\n",
    "When using this function in a doc, don't forget to apply `remove-input` tag to the cell for cleanliness\n",
    "```\n",
    "\n",
    "Embedding in this fashion has the benefit of allowing you to drop entire code blocks into a feature doc that may, for example, illustrate a usage example. Another great benefit of this method is that now your embedded example changes along with the code, so the docs maintain themselves.\n",
    "\n",
    "By default, docstrings will be included. There is an option to the directive to strip the docstrings:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "ff9a2b28",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:46:54.232491Z",
     "iopub.status.busy": "2026-10-02T14:46:54.232149Z",
     "iopub.status.idle": "2026-10-02T14:46:54.237489Z",
     "shell.execute_reply": "2026-10-02T14:46:54.236952Z"
    },
    "papermill": {
     "duration": 0.007746,
     "end_time": "2026-10-02T14:46:54.237931+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:54.230185+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<style>pre { line-height: 125%; }\n",
       "td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\n",
       "span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\n",
       "td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\n",
       "span.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\">RectangleComp</span><span class=\"p\">(</span><span class=\"n\">om</span><span class=\"o\">.</span><span class=\"n\">ExplicitComponent</span><span class=\"p\">):</span>\n",
       "    \n",
       "\n",
       "    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">setup</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_input</span><span class=\"p\">(</span><span class=\"s1\">&#39;length&#39;</span><span class=\"p\">,</span> <span class=\"n\">val</span><span class=\"o\">=</span><span class=\"mf\">1.</span><span class=\"p\">)</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_input</span><span class=\"p\">(</span><span class=\"s1\">&#39;width&#39;</span><span class=\"p\">,</span> <span class=\"n\">val</span><span class=\"o\">=</span><span class=\"mf\">1.</span><span class=\"p\">)</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_output</span><span class=\"p\">(</span><span class=\"s1\">&#39;area&#39;</span><span class=\"p\">,</span> <span class=\"n\">val</span><span class=\"o\">=</span><span class=\"mf\">1.</span><span class=\"p\">)</span>\n",
       "\n",
       "    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">setup_partials</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">declare_partials</span><span class=\"p\">(</span><span class=\"s1\">&#39;*&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;*&#39;</span><span class=\"p\">)</span>\n",
       "\n",
       "    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">compute</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">inputs</span><span class=\"p\">,</span> <span class=\"n\">outputs</span><span class=\"p\">):</span>\n",
       "        <span class=\"n\">outputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;area&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">inputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;length&#39;</span><span class=\"p\">]</span> <span class=\"o\">*</span> <span class=\"n\">inputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;width&#39;</span><span class=\"p\">]</span>\n",
       "</pre></div>\n"
      ],
      "text/latex": [
       "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n",
       "\\PY{k}{class}\\PY{+w}{ }\\PY{n+nc}{RectangleComp}\\PY{p}{(}\\PY{n}{om}\\PY{o}{.}\\PY{n}{ExplicitComponent}\\PY{p}{)}\\PY{p}{:}\n",
       "    \n",
       "\n",
       "    \\PY{k}{def}\\PY{+w}{ }\\PY{n+nf}{setup}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{p}{)}\\PY{p}{:}\n",
       "        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{add\\PYZus{}input}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{length}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{val}\\PY{o}{=}\\PY{l+m+mf}{1.}\\PY{p}{)}\n",
       "        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{add\\PYZus{}input}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{width}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{val}\\PY{o}{=}\\PY{l+m+mf}{1.}\\PY{p}{)}\n",
       "        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{add\\PYZus{}output}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{area}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{val}\\PY{o}{=}\\PY{l+m+mf}{1.}\\PY{p}{)}\n",
       "\n",
       "    \\PY{k}{def}\\PY{+w}{ }\\PY{n+nf}{setup\\PYZus{}partials}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{p}{)}\\PY{p}{:}\n",
       "        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{declare\\PYZus{}partials}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{*}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{*}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{)}\n",
       "\n",
       "    \\PY{k}{def}\\PY{+w}{ }\\PY{n+nf}{compute}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{p}{,} \\PY{n}{inputs}\\PY{p}{,} \\PY{n}{outputs}\\PY{p}{)}\\PY{p}{:}\n",
       "        \\PY{n}{outputs}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{area}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]} \\PY{o}{=} \\PY{n}{inputs}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{length}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]} \\PY{o}{*} \\PY{n}{inputs}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{width}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\n",
       "\\end{Verbatim}\n"
      ],
      "text/plain": [
       "class RectangleComp(om.ExplicitComponent):\n",
       "    \n",
       "\n",
       "    def setup(self):\n",
       "        self.add_input('length', val=1.)\n",
       "        self.add_input('width', val=1.)\n",
       "        self.add_output('area', val=1.)\n",
       "\n",
       "    def setup_partials(self):\n",
       "        self.declare_partials('*', '*')\n",
       "\n",
       "    def compute(self, inputs, outputs):\n",
       "        outputs['area'] = inputs['length'] * inputs['width']"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "om.display_source(\"openmdao.core.tests.test_expl_comp.RectangleComp\", hide_doc_string=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "74a558a9",
   "metadata": {
    "papermill": {
     "duration": 0.001306,
     "end_time": "2026-10-02T14:46:54.240621+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:54.239315+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "#### Embedding More Than Just Code\n",
    "\n",
    "Sometimes developers will want to embed code, code output, or even plots into a document. Because our docs use Jupyter Notebooks, developers are now able to embed code examples directly into the documents just like this notebook and even write tests for the examples. Below is an example of the flexibility this allows:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "66957791",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:46:54.244062Z",
     "iopub.status.busy": "2026-10-02T14:46:54.243930Z",
     "iopub.status.idle": "2026-10-02T14:46:55.524041Z",
     "shell.execute_reply": "2026-10-02T14:46:55.523086Z"
    },
    "papermill": {
     "duration": 1.282806,
     "end_time": "2026-10-02T14:46:55.524782+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:54.241976+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1790952415.466925] [runnervm8df0l:10841:0]        ib_iface.c:1269 UCX  ERROR mana_0: iface 0x55b86a06c280 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",
      "[1790952415.467176] [runnervm8df0l:10841:0]      ucp_worker.c:1412 UCX  ERROR uct_iface_open(ud_verbs/mana_0:1) failed: Input/output error\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Optimization terminated successfully    (Exit mode 0)\n",
      "            Current function value: -27.33333333333333\n",
      "            Iterations: 5\n",
      "            Function evaluations: 6\n",
      "            Gradient evaluations: 5\n",
      "Optimization Complete\n",
      "-----------------------------------\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[runnervm8df0l:10841] pml_ucx.c:313  Error: Failed to create UCP worker\n"
     ]
    }
   ],
   "source": [
    "# build the model\n",
    "prob = om.Problem()\n",
    "\n",
    "prob.model.add_subsystem('paraboloid', om.ExecComp('f = (x-3)**2 + x*y + (y+4)**2 - 3'))\n",
    "\n",
    "# setup the optimization\n",
    "prob.driver = om.ScipyOptimizeDriver()\n",
    "prob.driver.options['optimizer'] = 'SLSQP'\n",
    "\n",
    "prob.model.add_design_var('paraboloid.x', lower=-50, upper=50)\n",
    "prob.model.add_design_var('paraboloid.y', lower=-50, upper=50)\n",
    "prob.model.add_objective('paraboloid.f')\n",
    "\n",
    "prob.setup()\n",
    "\n",
    "# Set initial values.\n",
    "prob.set_val('paraboloid.x', 3.0)\n",
    "prob.set_val('paraboloid.y', -4.0)\n",
    "\n",
    "# run the optimization\n",
    "prob.run_driver();"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "20499ae5",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:46:55.530237Z",
     "iopub.status.busy": "2026-10-02T14:46:55.529835Z",
     "iopub.status.idle": "2026-10-02T14:46:55.534005Z",
     "shell.execute_reply": "2026-10-02T14:46:55.533355Z"
    },
    "papermill": {
     "duration": 0.007675,
     "end_time": "2026-10-02T14:46:55.534732+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:55.527057+00:00",
     "status": "completed"
    },
    "tags": [
     "allow-assert"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "np.float64(1.2195109964002665e-10)"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from openmdao.utils.assert_utils import assert_near_equal\n",
    "assert_near_equal(prob.get_val('paraboloid.x'), 6.66666666, tolerance=1.0E-5)\n",
    "assert_near_equal(prob.get_val('paraboloid.y'), -7.33333333, tolerance=1.0E-5)\n",
    "assert_near_equal(prob.get_val('paraboloid.f'), -27.33333333, tolerance=1.0E-5)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b54ad1ac",
   "metadata": {
    "papermill": {
     "duration": 0.002226,
     "end_time": "2026-10-02T14:46:55.637078+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:55.634852+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "When adding tests, use `remove-output` and `remove-input` to keep the docs clean while still allowing tests to be run when building the docs.\n",
    "\n",
    "If you want to hide the output use the `remove-output` tag and/or `remove-input` to hide the code when the doc gets built. To add tags in Jupyter Notebook, navigate to `View` -> `Cell Toolbar` -> `Tags`. The output includes any output that the script produces, including plots. Below is an example of `remove-output`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "75b424ab",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:46:55.665648Z",
     "iopub.status.busy": "2026-10-02T14:46:55.665405Z",
     "iopub.status.idle": "2026-10-02T14:46:55.679319Z",
     "shell.execute_reply": "2026-10-02T14:46:55.678755Z"
    },
    "papermill": {
     "duration": 0.017729,
     "end_time": "2026-10-02T14:46:55.680134+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:55.662405+00:00",
     "status": "completed"
    },
    "tags": [
     "remove-output"
    ]
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Optimization terminated successfully    (Exit mode 0)\n",
      "            Current function value: -27.33333333333333\n",
      "            Iterations: 5\n",
      "            Function evaluations: 6\n",
      "            Gradient evaluations: 5\n",
      "Optimization Complete\n",
      "-----------------------------------\n"
     ]
    }
   ],
   "source": [
    "# build the model\n",
    "prob = om.Problem()\n",
    "\n",
    "prob.model.add_subsystem('paraboloid', om.ExecComp('f = (x-3)**2 + x*y + (y+4)**2 - 3'))\n",
    "\n",
    "# setup the optimization\n",
    "prob.driver = om.ScipyOptimizeDriver()\n",
    "prob.driver.options['optimizer'] = 'SLSQP'\n",
    "\n",
    "prob.model.add_design_var('paraboloid.x', lower=-50, upper=50)\n",
    "prob.model.add_design_var('paraboloid.y', lower=-50, upper=50)\n",
    "prob.model.add_objective('paraboloid.f')\n",
    "\n",
    "prob.setup()\n",
    "\n",
    "# Set initial values.\n",
    "prob.set_val('paraboloid.x', 3.0)\n",
    "prob.set_val('paraboloid.y', -4.0)\n",
    "\n",
    "# run the optimization\n",
    "prob.run_driver();"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ca18ca42",
   "metadata": {
    "papermill": {
     "duration": 0.001987,
     "end_time": "2026-10-02T14:46:55.684228+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:55.682241+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "The tests will automatically detect if you have an assert in a cell but forgot to tag it with `remove-output` and `remove-input`.  If you need to include an assert in a visible cell block, you can tag that block with `allow-assert` so that the test will skip it.\n",
    "\n",
    "### `show_options_table`\n",
    "\n",
    "`om.show_options_table()` is function that lets a developer display a set of options directly into a feature doc by including the module dot path name. The syntax for invoking the directive looks like this:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "be17b0a6",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:46:55.689188Z",
     "iopub.status.busy": "2026-10-02T14:46:55.689010Z",
     "iopub.status.idle": "2026-10-02T14:46:55.692552Z",
     "shell.execute_reply": "2026-10-02T14:46:55.692078Z"
    },
    "papermill": {
     "duration": 0.006816,
     "end_time": "2026-10-02T14:46:55.693127+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:55.686311+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;\">Option</th><th style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; background-color: #E9E9E9; text-align: left;\">Default</th><th style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; background-color: #E9E9E9; text-align: left;\">Acceptable Values</th><th style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; background-color: #E9E9E9; text-align: left;\">Acceptable Types</th><th style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; background-color: #E9E9E9; text-align: left;\">Description</th></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">assemble_jac</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">False</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">[True, False]</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">[&#x27;bool&#x27;]</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">Activates use of assembled jacobian by this solver.</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">atol</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">1e-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: 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;\">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",
       "    </table>\n",
       "</body>\n",
       "</html>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "om.show_options_table(\"openmdao.solvers.linear.linear_block_jac.LinearBlockJac\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a166cfc9",
   "metadata": {
    "papermill": {
     "duration": 0.002069,
     "end_time": "2026-10-02T14:46:55.697342+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:55.695273+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "### Shell Commands\n",
    "\n",
    "If a developer wants to run a shell command, all they need to do is start the line with `!`. For example: "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "a6bd1538",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:46:55.702437Z",
     "iopub.status.busy": "2026-10-02T14:46:55.702175Z",
     "iopub.status.idle": "2026-10-02T14:47:00.425285Z",
     "shell.execute_reply": "2026-10-02T14:47:00.424560Z"
    },
    "papermill": {
     "duration": 4.726971,
     "end_time": "2026-10-02T14:47:00.426376+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:46:55.699405+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1790952419.291010] [runnervm8df0l:10901:0]        ib_iface.c:1269 UCX  ERROR mana_0: iface 0x55ca85787480 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\r\n",
      "[1790952419.291270] [runnervm8df0l:10901:0]      ucp_worker.c:1412 UCX  ERROR uct_iface_open(ud_verbs/mana_0:1) failed: Input/output error\r\n",
      "[runnervm8df0l:10901] pml_ucx.c:313  Error: Failed to create UCP worker\r\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Driver: \u001b[0mDriver\r\n",
      "\u001b[0m    \u001b[0mGroup \u001b[0m\u001b[0m\r\n",
      "\u001b[0m        \u001b[0mIndepVarComp \u001b[0mground\u001b[0m\r\n",
      "\u001b[0m        \u001b[0mIndepVarComp \u001b[0msource\u001b[0m\r\n",
      "\u001b[0m        \u001b[0mCircuit \u001b[0mcircuit\u001b[0m  LN: \u001b[0mDirectSolver\u001b[0m  NL: \u001b[0mNewtonSolver\u001b[0m\r\n",
      "\u001b[0m            \u001b[0mNode \u001b[0mn1\u001b[0m\r\n",
      "\u001b[0m            \u001b[0mNode \u001b[0mn2\u001b[0m\r\n",
      "\u001b[0m            \u001b[0mResistor \u001b[0mR1\u001b[0m\r\n",
      "\u001b[0m            \u001b[0mResistor \u001b[0mR2\u001b[0m\r\n",
      "\u001b[0m            \u001b[0mDiode \u001b[0mD1\u001b[0m\r\n",
      "\u001b[0m\u001b[0m"
     ]
    }
   ],
   "source": [
    "!openmdao tree ../circuit.py"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6e480c8f",
   "metadata": {
    "papermill": {
     "duration": 0.002434,
     "end_time": "2026-10-02T14:47:00.431455+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:47:00.429021+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "### Citations\n",
    "\n",
    "To insert a citation, use `om.cite()`. The single argument is the module dot path or the name of a function that returns an instance of the desired class when called with no arguments."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "2d9613a8",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:47:00.437296Z",
     "iopub.status.busy": "2026-10-02T14:47:00.437070Z",
     "iopub.status.idle": "2026-10-02T14:47:00.440566Z",
     "shell.execute_reply": "2026-10-02T14:47:00.439747Z"
    },
    "papermill": {
     "duration": 0.007312,
     "end_time": "2026-10-02T14:47:00.441126+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:47:00.433814+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "@article{Hwang_maud_2018\n",
      " author = {Hwang, John T. and Martins, Joaquim R.R.A.},\n",
      " title = \"{A Computational Architecture for Coupling Heterogeneous\n",
      "          Numerical Models and Computing Coupled Derivatives}\",\n",
      " journal = \"{ACM Trans. Math. Softw.}\",\n",
      " volume = {44},\n",
      " number = {4},\n",
      " month = jun,\n",
      " year = {2018},\n",
      " pages = {37:1--37:39},\n",
      " articleno = {37},\n",
      " numpages = {39},\n",
      " doi = {10.1145/3182393},\n",
      " publisher = {ACM},\n",
      "\n"
     ]
    }
   ],
   "source": [
    "om.cite(\"openmdao.drivers.scipy_optimizer.ScipyOptimizeDriver\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "59653ad4",
   "metadata": {
    "papermill": {
     "duration": 0.002209,
     "end_time": "2026-10-02T14:47:00.446766+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:47:00.444557+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "### N2\n",
    "\n",
    "To embed an `N2` diagram simply call `om.n2()` inside of a Jupyter code cell and the output will be automatically formatted and displayed when given a case file or `om.Problem()`. In the example below, we will display the n2 from the paraboloid example from above."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "77f573fc",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:47:00.500256Z",
     "iopub.status.busy": "2026-10-02T14:47:00.500076Z",
     "iopub.status.idle": "2026-10-02T14:47:00.545329Z",
     "shell.execute_reply": "2026-10-02T14:47:00.544622Z"
    },
    "papermill": {
     "duration": 0.096829,
     "end_time": "2026-10-02T14:47:00.545853+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:47:00.449024+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "        <iframe\n",
       "            width=\"100%\"\n",
       "            height=\"700\"\n",
       "            src=\"n2.html\"\n",
       "            frameborder=\"0\"\n",
       "            allowfullscreen\n",
       "            \n",
       "        ></iframe>\n",
       "        "
      ],
      "text/plain": [
       "<IPython.lib.display.IFrame at 0x7fb763f7aba0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "om.n2(prob)"
   ]
  }
 ],
 "metadata": {
  "celltoolbar": "Tags",
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.14"
  },
  "orphan": true,
  "papermill": {
   "default_parameters": {},
   "duration": 8.918899,
   "end_time": "2026-10-02T14:47:01.164009+00:00",
   "environment_variables": {},
   "exception": null,
   "input_path": "/home/runner/work/OpenMDAO/OpenMDAO/openmdao/docs/openmdao_book/other_useful_docs/developer_docs/doc_style_guide.ipynb",
   "output_path": "/home/runner/work/OpenMDAO/OpenMDAO/openmdao/docs/_executed_book/other_useful_docs/developer_docs/doc_style_guide.ipynb",
   "parameters": {},
   "start_time": "2026-10-02T14:46:52.245110+00:00",
   "version": "2.7.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}