{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "447e3732",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:48:25.244526Z",
     "iopub.status.busy": "2026-10-02T14:48:25.244312Z",
     "iopub.status.idle": "2026-10-02T14:48:25.248748Z",
     "shell.execute_reply": "2026-10-02T14:48:25.248064Z"
    },
    "hide_input": true,
    "papermill": {
     "duration": 0.007838,
     "end_time": "2026-10-02T14:48:25.249232+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:48:25.241394+00:00",
     "status": "completed"
    },
    "tags": [
     "active-ipynb",
     "remove-input",
     "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]"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "4ad0a6b0",
   "metadata": {
    "papermill": {
     "duration": 0.034304,
     "end_time": "2026-10-02T14:48:25.303126+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:48:25.268822+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "# DOEDriver\n",
    "\n",
    "DOEDriver facilitates performing a design of experiments (DOE) with your OpenMDAO model. It will run your model multiple times with different values for the design variables depending on the selected input generator. A number of generators are available, each with its own parameters that can be specified when it is instantiated:\n",
    "\n",
    "  - UniformGenerator\n",
    "  - FullFactorialGenerator\n",
    "  - PlackettBurmanGenerator\n",
    "  - BoxBehnkenGenerator\n",
    "  - LatinHypercubeGenerator\n",
    "  - CSVGenerator\n",
    "  - ListGenerator\n",
    "\n",
    "See the [source documentation](../../../_srcdocs/packages/drivers/doe_generators) of these generators for details.\n",
    "\n",
    "```{Note}\n",
    "`FullFactorialGenerator`, `PlackettBurmanGenerator`, `BoxBehnkenGenerator` and `LatinHypercubeGenerator` are provided via the [pydoe](https://pypi.org/project/pydoe/) package, the actively maintained continuation of pyDOE2 and pyDOE3. See the [PyDOE documentation](https://pydoe.github.io/pydoe/) for information on those algorithms.\n",
    "```\n",
    "\n",
    "The generator instance may be supplied as an argument to the `DOEDriver` or as an option.\n",
    "\n",
    "## DOEDriver Options"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "7b5cf235",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:48:25.306981Z",
     "iopub.status.busy": "2026-10-02T14:48:25.306826Z",
     "iopub.status.idle": "2026-10-02T14:48:26.428276Z",
     "shell.execute_reply": "2026-10-02T14:48:26.427559Z"
    },
    "papermill": {
     "duration": 1.124115,
     "end_time": "2026-10-02T14:48:26.428719+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:48:25.304604+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;\">debug_print</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">[]</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">[&#x27;desvars&#x27;, &#x27;nl_cons&#x27;, &#x27;ln_cons&#x27;, &#x27;objs&#x27;, &#x27;totals&#x27;]</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">[&#x27;list&#x27;]</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">List of what type of Driver variables to print at each iteration.</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">generator</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">DOEGenerator</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;DOEGenerator&#x27;]</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">The case generator. If default, no cases are generated.</td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">invalid_desvar_behavior</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">warn</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">[&#x27;warn&#x27;, &#x27;raise&#x27;, &#x27;ignore&#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;\">Behavior of driver if the initial value of a design variable exceeds its bounds. The default value may beset using the `OPENMDAO_INVALID_DESVAR_BEHAVIOR` environment variable to one of the valid options.</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">procs_per_model</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;\">Number of processors to give each model under MPI.</td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">run_parallel</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">False</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">[True, False]</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">[&#x27;bool&#x27;]</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">Set to True to execute cases in parallel.</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.drivers.doe_driver.DOEDriver\")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "770f69da",
   "metadata": {
    "papermill": {
     "duration": 0.001454,
     "end_time": "2026-10-02T14:48:26.431995+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:48:26.430541+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "## DOEDriver Constructor\n",
    "\n",
    "The call signature for the `DOEDriver` constructor is:\n",
    "\n",
    "```{eval-rst}\n",
    "    .. automethod:: openmdao.drivers.doe_driver.DOEDriver.__init__\n",
    "       :noindex:\n",
    "```  \n",
    "\n",
    "## Simple Example\n",
    "\n",
    "`UniformGenerator` implements the simplest method and will generate a requested number of samples randomly selected from a uniform distribution across the valid range for each design variable. This example demonstrates its use with a model built on the [Paraboloid](../../../basic_user_guide/single_disciplinary_optimization/first_analysis) Component. An [SqliteRecorder](../../../_srcdocs/packages/recorders/sqlite_recorder) is used to capture the cases that were generated. We can see that that the model was evaluated at random values of x and y between -10 and 10, per the lower and upper bounds of those design variables."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "4b55f34c",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:48:26.706584Z",
     "iopub.status.busy": "2026-10-02T14:48:26.706167Z",
     "iopub.status.idle": "2026-10-02T14:48:27.483838Z",
     "shell.execute_reply": "2026-10-02T14:48:27.482953Z"
    },
    "papermill": {
     "duration": 1.050852,
     "end_time": "2026-10-02T14:48:27.484395+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:48:26.433543+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\">Paraboloid</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\">    Evaluates the equation f(x,y) = (x-3)^2 + xy + (y+4)^2 - 3.</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;x&#39;</span><span class=\"p\">,</span> <span class=\"n\">val</span><span class=\"o\">=</span><span class=\"mf\">0.0</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;y&#39;</span><span class=\"p\">,</span> <span class=\"n\">val</span><span class=\"o\">=</span><span class=\"mf\">0.0</span><span class=\"p\">)</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_output</span><span class=\"p\">(</span><span class=\"s1\">&#39;f_xy&#39;</span><span class=\"p\">,</span> <span class=\"n\">val</span><span class=\"o\">=</span><span class=\"mf\">0.0</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=\"w\">        </span><span class=\"sd\">&quot;&quot;&quot;</span>\n<span class=\"sd\">        f(x,y) = (x-3)^2 + xy + (y+4)^2 - 3</span>\n\n<span class=\"sd\">        Optimal solution (minimum): x = 6.6667; y = -7.3333</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"n\">x</span> <span class=\"o\">=</span> <span class=\"n\">inputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;x&#39;</span><span class=\"p\">]</span>\n        <span class=\"n\">y</span> <span class=\"o\">=</span> <span class=\"n\">inputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;y&#39;</span><span class=\"p\">]</span>\n\n        <span class=\"n\">outputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;f_xy&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"p\">(</span><span class=\"n\">x</span><span class=\"o\">-</span><span class=\"mf\">3.0</span><span class=\"p\">)</span><span class=\"o\">**</span><span class=\"mi\">2</span> <span class=\"o\">+</span> <span class=\"n\">x</span><span class=\"o\">*</span><span class=\"n\">y</span> <span class=\"o\">+</span> <span class=\"p\">(</span><span class=\"n\">y</span><span class=\"o\">+</span><span class=\"mf\">4.0</span><span class=\"p\">)</span><span class=\"o\">**</span><span class=\"mi\">2</span> <span class=\"o\">-</span> <span class=\"mf\">3.0</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">compute_partials</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">inputs</span><span class=\"p\">,</span> <span class=\"n\">partials</span><span class=\"p\">):</span>\n<span class=\"w\">        </span><span class=\"sd\">&quot;&quot;&quot;</span>\n<span class=\"sd\">        Jacobian for our paraboloid.</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"n\">x</span> <span class=\"o\">=</span> <span class=\"n\">inputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;x&#39;</span><span class=\"p\">]</span>\n        <span class=\"n\">y</span> <span class=\"o\">=</span> <span class=\"n\">inputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;y&#39;</span><span class=\"p\">]</span>\n\n        <span class=\"n\">partials</span><span class=\"p\">[</span><span class=\"s1\">&#39;f_xy&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;x&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"mf\">2.0</span><span class=\"o\">*</span><span class=\"n\">x</span> <span class=\"o\">-</span> <span class=\"mf\">6.0</span> <span class=\"o\">+</span> <span class=\"n\">y</span>\n        <span class=\"n\">partials</span><span class=\"p\">[</span><span class=\"s1\">&#39;f_xy&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;y&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"mf\">2.0</span><span class=\"o\">*</span><span class=\"n\">y</span> <span class=\"o\">+</span> <span class=\"mf\">8.0</span> <span class=\"o\">+</span> <span class=\"n\">x</span>\n</pre></div>\n",
      "application/papermill.record/text/latex": "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n\\PY{k}{class}\\PY{+w}{ }\\PY{n+nc}{Paraboloid}\\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}{    Evaluates the equation f(x,y) = (x\\PYZhy{}3)\\PYZca{}2 + xy + (y+4)\\PYZca{}2 \\PYZhy{} 3.}\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}{x}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{val}\\PY{o}{=}\\PY{l+m+mf}{0.0}\\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}{y}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{val}\\PY{o}{=}\\PY{l+m+mf}{0.0}\\PY{p}{)}\n\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{add\\PYZus{}output}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{f\\PYZus{}xy}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{val}\\PY{o}{=}\\PY{l+m+mf}{0.0}\\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{+w}{        }\\PY{l+s+sd}{\\PYZdq{}\\PYZdq{}\\PYZdq{}}\n\\PY{l+s+sd}{        f(x,y) = (x\\PYZhy{}3)\\PYZca{}2 + xy + (y+4)\\PYZca{}2 \\PYZhy{} 3}\n\n\\PY{l+s+sd}{        Optimal solution (minimum): x = 6.6667; y = \\PYZhy{}7.3333}\n\\PY{l+s+sd}{        \\PYZdq{}\\PYZdq{}\\PYZdq{}}\n        \\PY{n}{x} \\PY{o}{=} \\PY{n}{inputs}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{x}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\n        \\PY{n}{y} \\PY{o}{=} \\PY{n}{inputs}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{y}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\n\n        \\PY{n}{outputs}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{f\\PYZus{}xy}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]} \\PY{o}{=} \\PY{p}{(}\\PY{n}{x}\\PY{o}{\\PYZhy{}}\\PY{l+m+mf}{3.0}\\PY{p}{)}\\PY{o}{*}\\PY{o}{*}\\PY{l+m+mi}{2} \\PY{o}{+} \\PY{n}{x}\\PY{o}{*}\\PY{n}{y} \\PY{o}{+} \\PY{p}{(}\\PY{n}{y}\\PY{o}{+}\\PY{l+m+mf}{4.0}\\PY{p}{)}\\PY{o}{*}\\PY{o}{*}\\PY{l+m+mi}{2} \\PY{o}{\\PYZhy{}} \\PY{l+m+mf}{3.0}\n\n    \\PY{k}{def}\\PY{+w}{ }\\PY{n+nf}{compute\\PYZus{}partials}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{p}{,} \\PY{n}{inputs}\\PY{p}{,} \\PY{n}{partials}\\PY{p}{)}\\PY{p}{:}\n\\PY{+w}{        }\\PY{l+s+sd}{\\PYZdq{}\\PYZdq{}\\PYZdq{}}\n\\PY{l+s+sd}{        Jacobian for our paraboloid.}\n\\PY{l+s+sd}{        \\PYZdq{}\\PYZdq{}\\PYZdq{}}\n        \\PY{n}{x} \\PY{o}{=} \\PY{n}{inputs}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{x}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\n        \\PY{n}{y} \\PY{o}{=} \\PY{n}{inputs}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{y}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\n\n        \\PY{n}{partials}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{f\\PYZus{}xy}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{x}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]} \\PY{o}{=} \\PY{l+m+mf}{2.0}\\PY{o}{*}\\PY{n}{x} \\PY{o}{\\PYZhy{}} \\PY{l+m+mf}{6.0} \\PY{o}{+} \\PY{n}{y}\n        \\PY{n}{partials}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{f\\PYZus{}xy}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{y}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]} \\PY{o}{=} \\PY{l+m+mf}{2.0}\\PY{o}{*}\\PY{n}{y} \\PY{o}{+} \\PY{l+m+mf}{8.0} \\PY{o}{+} \\PY{n}{x}\n\\end{Verbatim}\n",
      "application/papermill.record/text/plain": "class Paraboloid(om.ExplicitComponent):\n    \"\"\"\n    Evaluates the equation f(x,y) = (x-3)^2 + xy + (y+4)^2 - 3.\n    \"\"\"\n\n    def setup(self):\n        self.add_input('x', val=0.0)\n        self.add_input('y', val=0.0)\n\n        self.add_output('f_xy', val=0.0)\n\n    def setup_partials(self):\n        self.declare_partials('*', '*')\n\n    def compute(self, inputs, outputs):\n        \"\"\"\n        f(x,y) = (x-3)^2 + xy + (y+4)^2 - 3\n\n        Optimal solution (minimum): x = 6.6667; y = -7.3333\n        \"\"\"\n        x = inputs['x']\n        y = inputs['y']\n\n        outputs['f_xy'] = (x-3.0)**2 + x*y + (y+4.0)**2 - 3.0\n\n    def compute_partials(self, inputs, partials):\n        \"\"\"\n        Jacobian for our paraboloid.\n        \"\"\"\n        x = inputs['x']\n        y = inputs['y']\n\n        partials['f_xy', 'x'] = 2.0*x - 6.0 + y\n        partials['f_xy', 'y'] = 2.0*y + 8.0 + x"
     },
     "metadata": {
      "scrapbook": {
       "mime_prefix": "application/papermill.record/",
       "name": "code_src16"
      }
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "from openmdao.utils.notebook_utils import get_code\n",
    "from myst_nb import glue\n",
    "glue(\"code_src16\", get_code(\"openmdao.test_suite.components.paraboloid.Paraboloid\"), display=False)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "de45e11b",
   "metadata": {
    "papermill": {
     "duration": 0.001602,
     "end_time": "2026-10-02T14:48:27.487884+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:48:27.486282+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    ":::{dropdown} `Paraboloid` class definition \n",
    "\n",
    "{glue:}`code_src16`\n",
    ":::"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "72eb78ea",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:48:27.631196Z",
     "iopub.status.busy": "2026-10-02T14:48:27.630967Z",
     "iopub.status.idle": "2026-10-02T14:48:29.281343Z",
     "shell.execute_reply": "2026-10-02T14:48:29.280673Z"
    },
    "papermill": {
     "duration": 1.792515,
     "end_time": "2026-10-02T14:48:29.281952+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:48:27.489437+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1790952508.831015] [runnervm8df0l:11365:0]        ib_iface.c:1269 UCX  ERROR mana_0: iface 0x55ba960d6b00 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",
      "[1790952508.831285] [runnervm8df0l:11365:0]      ucp_worker.c:1412 UCX  ERROR uct_iface_open(ud_verbs/mana_0:1) failed: Input/output error\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[runnervm8df0l:11365] pml_ucx.c:313  Error: Failed to create UCP worker\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "\n",
       "<!DOCTYPE html>\n",
       "<html lang=\"en\">\n",
       "<head>\n",
       "    <style>\n",
       "        h2 {\n",
       "            text-align: center;\n",
       "        }\n",
       "    </style>\n",
       "</head>\n",
       "<body>\n",
       "    <h2></h2>\n",
       "        <table style=\"border: 1px solid #999; border-collapse: collapse;\">\n",
       "        <tr><th style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; background-color: #E9E9E9; text-align: left;\">driver</th></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:DOEDriver_Uniform|0</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:DOEDriver_Uniform|1</td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:DOEDriver_Uniform|2</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:DOEDriver_Uniform|3</td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">rank0:DOEDriver_Uniform|4</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",
    "from openmdao.test_suite.components.paraboloid import Paraboloid\n",
    "\n",
    "prob = om.Problem()\n",
    "model = prob.model\n",
    "\n",
    "model.add_subsystem('comp', Paraboloid(), promotes=['*'])\n",
    "\n",
    "model.add_design_var('x', lower=-10, upper=10)\n",
    "model.add_design_var('y', lower=-10, upper=10)\n",
    "model.add_objective('f_xy')\n",
    "\n",
    "prob.driver = om.DOEDriver(om.UniformGenerator(num_samples=5))\n",
    "prob.driver.add_recorder(om.SqliteRecorder(\"doe_driver.sql\"))\n",
    "\n",
    "prob.setup()\n",
    "\n",
    "prob.set_val('x', 0.0)\n",
    "prob.set_val('y', 0.0)\n",
    "\n",
    "prob.run_driver()\n",
    "prob.cleanup()\n",
    "\n",
    "cr = om.CaseReader(prob.get_outputs_dir() / \"doe_driver.sql\")\n",
    "cases = cr.list_cases('driver')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "9f01aab1",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:48:29.286954Z",
     "iopub.status.busy": "2026-10-02T14:48:29.286801Z",
     "iopub.status.idle": "2026-10-02T14:48:29.290262Z",
     "shell.execute_reply": "2026-10-02T14:48:29.289458Z"
    },
    "papermill": {
     "duration": 0.006565,
     "end_time": "2026-10-02T14:48:29.290721+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:48:29.284156+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x: -9.24, y:  8.37, f_xy: 222.44\n",
      "x: -9.02, y: -5.34, f_xy: 191.40\n",
      "x: -0.49, y: -2.28, f_xy:  13.23\n",
      "x: -4.63, y: -9.15, f_xy: 124.12\n",
      "x: -4.45, y:  8.71, f_xy: 175.32\n"
     ]
    }
   ],
   "source": [
    "values = []\n",
    "for case in cases:\n",
    "    outputs = cr.get_case(case).outputs\n",
    "    values.append((outputs['x'].item(), outputs['y'].item(), outputs['f_xy'].item()))\n",
    "\n",
    "print(\"\\n\".join([\"x: %5.2f, y: %5.2f, f_xy: %6.2f\" % xyf for xyf in values]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "25b7425d",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:48:29.335563Z",
     "iopub.status.busy": "2026-10-02T14:48:29.335412Z",
     "iopub.status.idle": "2026-10-02T14:48:29.337874Z",
     "shell.execute_reply": "2026-10-02T14:48:29.337198Z"
    },
    "papermill": {
     "duration": 0.045592,
     "end_time": "2026-10-02T14:48:29.338278+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:48:29.292686+00:00",
     "status": "completed"
    },
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "assert(len(cases) == 5)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "e57a035a",
   "metadata": {
    "papermill": {
     "duration": 0.001593,
     "end_time": "2026-10-02T14:48:29.349744+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:48:29.348151+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "## Running a DOE in Parallel\n",
    "\n",
    "In a parallel processing environment, it is possible for `DOEDriver` to run cases concurrently. This is done by setting the `run_parallel` option to True as shown in the following example and running your script using MPI.\n",
    "\n",
    "Here we are using the `FullFactorialGenerator` with 3 levels to generate inputs for our Paraboloid model. With two inputs, $3^2=9$ cases have been generated. In this case we are running on four processors and have specified `options['run_parallel']=True` to run cases on all available processors. The cases have therefore been split with 3 cases run on the first processor and 2 cases on each of the other processors.\n",
    "\n",
    "Note that, when running in parallel, the `SqliteRecorder` will generate a separate case file for each processor on which cases are recorded. The case files will have a suffix indicating the recording rank and a message will be displayed indicating the file name, as seen in the example."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "a76695ce",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:48:29.353816Z",
     "iopub.status.busy": "2026-10-02T14:48:29.353630Z",
     "iopub.status.idle": "2026-10-02T14:48:29.357401Z",
     "shell.execute_reply": "2026-10-02T14:48:29.356669Z"
    },
    "papermill": {
     "duration": 0.006528,
     "end_time": "2026-10-02T14:48:29.357818+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:48:29.351290+00:00",
     "status": "completed"
    },
    "tags": [
     "remove-cell"
    ]
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Overwriting mpi_script_0.py\n"
     ]
    }
   ],
   "source": [
    "%%writefile mpi_script_0.py\n",
    "import openmdao.api as om\n",
    "from openmdao.test_suite.components.paraboloid import Paraboloid\n",
    "\n",
    "prob = om.Problem()\n",
    "\n",
    "prob.model.add_subsystem('comp', Paraboloid(), promotes=['x', 'y', 'f_xy'])\n",
    "prob.model.add_design_var('x', lower=0.0, upper=1.0)\n",
    "prob.model.add_design_var('y', lower=0.0, upper=1.0)\n",
    "prob.model.add_objective('f_xy')\n",
    "\n",
    "prob.driver = om.DOEDriver(om.FullFactorialGenerator(levels=3))\n",
    "prob.driver.options['run_parallel'] = True\n",
    "prob.driver.options['procs_per_model'] = 1\n",
    "\n",
    "prob.driver.add_recorder(om.SqliteRecorder(\"doe_driver.sql\"))\n",
    "\n",
    "prob.setup()\n",
    "prob.run_driver()\n",
    "prob.cleanup()\n",
    "\n",
    "# check recorded cases from each case file\n",
    "from mpi4py import MPI\n",
    "rank = MPI.COMM_WORLD.rank\n",
    "\n",
    "filename = \"doe_driver.sql_%d\" % rank\n",
    "\n",
    "cr = om.CaseReader(prob.get_outputs_dir() / filename)\n",
    "cases = cr.list_cases('driver', out_stream=None)\n",
    "print(cases)\n",
    "\n",
    "values = []\n",
    "for case in cases:\n",
    "    outputs = cr.get_case(case).outputs\n",
    "    values.append((outputs['x'].item(), outputs['y'].item(), outputs['f_xy'].item()))\n",
    "\n",
    "print(\"\\n\"+\"\\n\".join([\"x: %5.2f, y: %5.2f, f_xy: %6.2f\" % xyf for xyf in values]))\n",
    "\n",
    "import numpy as np\n",
    "\n",
    "assert(len(cases) == 3 if rank == 0 else 2)\n",
    "if rank == 0:\n",
    "    expected = [\n",
    "        {'x': np.array([0.]), 'y': np.array([0.]), 'f_xy': np.array([22.00])},\n",
    "        {'x': np.array([.5]), 'y': np.array([.5]), 'f_xy': np.array([23.75])},\n",
    "        {'x': np.array([1.]), 'y': np.array([1.]), 'f_xy': np.array([27.00])}]\n",
    "elif rank == 1:\n",
    "    expected = [\n",
    "        {'x': np.array([.5]), 'y': np.array([0.]), 'f_xy': np.array([19.25])},\n",
    "        {'x': np.array([1.]), 'y': np.array([.5]), 'f_xy': np.array([21.75])}]\n",
    "elif rank == 2:\n",
    "    expected = [\n",
    "        {'x': np.array([1.]), 'y': np.array([0.]), 'f_xy': np.array([17.00])},\n",
    "        {'x': np.array([0.]), 'y': np.array([1.]), 'f_xy': np.array([31.00])}]\n",
    "else:\n",
    "    expected = [\n",
    "        {'x': np.array([0.]), 'y': np.array([.5]), 'f_xy': np.array([26.25])},\n",
    "        {'x': np.array([.5]), 'y': np.array([1.]), 'f_xy': np.array([28.75])}]\n",
    "\n",
    "\n",
    "exp_values = []\n",
    "for case in expected:\n",
    "    exp_values.append((case['x'].item(), case['y'].item(), case['f_xy'].item()))\n",
    "expect_text = \"\\n\"+\"\\n\".join([\"x: %5.2f, y: %5.2f, f_xy: %6.2f\" % vals_i for vals_i in exp_values])\n",
    "\n",
    "assert(\"\\n\"+\"\\n\".join([\"x: %5.2f, y: %5.2f, f_xy: %6.2f\" % xyf for xyf in values]) == expect_text)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "4bf6be58",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:48:29.361938Z",
     "iopub.status.busy": "2026-10-02T14:48:29.361814Z",
     "iopub.status.idle": "2026-10-02T14:48:33.631140Z",
     "shell.execute_reply": "2026-10-02T14:48:33.630526Z"
    },
    "papermill": {
     "duration": 4.272536,
     "end_time": "2026-10-02T14:48:33.632023+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:48:29.359487+00:00",
     "status": "completed"
    },
    "tags": [
     "remove-input"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div class=\"admonition note\"><p class=\"admonition-title\">Note</p><p>This feature requires MPI, and may not be able to be run on Colab or Binder.</p></div>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<p>The following script is executed using <code>mpiexec -n 4 mpi_script_0.py</code>:</p><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",
       ".highlight .hll { background-color: #ffffcc }\n",
       ".highlight { background: #f8f8f8; }\n",
       ".highlight .c { color: #3D7B7B; font-style: italic } /* Comment */\n",
       ".highlight .err { border: 1px solid #F00 } /* Error */\n",
       ".highlight .k { color: #008000; font-weight: bold } /* Keyword */\n",
       ".highlight .o { color: #666 } /* Operator */\n",
       ".highlight .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */\n",
       ".highlight .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */\n",
       ".highlight .cp { color: #9C6500 } /* Comment.Preproc */\n",
       ".highlight .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */\n",
       ".highlight .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */\n",
       ".highlight .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */\n",
       ".highlight .gd { color: #A00000 } /* Generic.Deleted */\n",
       ".highlight .ge { font-style: italic } /* Generic.Emph */\n",
       ".highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */\n",
       ".highlight .gr { color: #E40000 } /* Generic.Error */\n",
       ".highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n",
       ".highlight .gi { color: #008400 } /* Generic.Inserted */\n",
       ".highlight .go { color: #717171 } /* Generic.Output */\n",
       ".highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */\n",
       ".highlight .gs { font-weight: bold } /* Generic.Strong */\n",
       ".highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n",
       ".highlight .gt { color: #04D } /* Generic.Traceback */\n",
       ".highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */\n",
       ".highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */\n",
       ".highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */\n",
       ".highlight .kp { color: #008000 } /* Keyword.Pseudo */\n",
       ".highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */\n",
       ".highlight .kt { color: #B00040 } /* Keyword.Type */\n",
       ".highlight .m { color: #666 } /* Literal.Number */\n",
       ".highlight .s { color: #BA2121 } /* Literal.String */\n",
       ".highlight .na { color: #687822 } /* Name.Attribute */\n",
       ".highlight .nb { color: #008000 } /* Name.Builtin */\n",
       ".highlight .nc { color: #00F; font-weight: bold } /* Name.Class */\n",
       ".highlight .no { color: #800 } /* Name.Constant */\n",
       ".highlight .nd { color: #A2F } /* Name.Decorator */\n",
       ".highlight .ni { color: #717171; font-weight: bold } /* Name.Entity */\n",
       ".highlight .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */\n",
       ".highlight .nf { color: #00F } /* Name.Function */\n",
       ".highlight .nl { color: #767600 } /* Name.Label */\n",
       ".highlight .nn { color: #00F; font-weight: bold } /* Name.Namespace */\n",
       ".highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */\n",
       ".highlight .nv { color: #19177C } /* Name.Variable */\n",
       ".highlight .ow { color: #A2F; font-weight: bold } /* Operator.Word */\n",
       ".highlight .w { color: #BBB } /* Text.Whitespace */\n",
       ".highlight .mb { color: #666 } /* Literal.Number.Bin */\n",
       ".highlight .mf { color: #666 } /* Literal.Number.Float */\n",
       ".highlight .mh { color: #666 } /* Literal.Number.Hex */\n",
       ".highlight .mi { color: #666 } /* Literal.Number.Integer */\n",
       ".highlight .mo { color: #666 } /* Literal.Number.Oct */\n",
       ".highlight .sa { color: #BA2121 } /* Literal.String.Affix */\n",
       ".highlight .sb { color: #BA2121 } /* Literal.String.Backtick */\n",
       ".highlight .sc { color: #BA2121 } /* Literal.String.Char */\n",
       ".highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */\n",
       ".highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */\n",
       ".highlight .s2 { color: #BA2121 } /* Literal.String.Double */\n",
       ".highlight .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */\n",
       ".highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */\n",
       ".highlight .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */\n",
       ".highlight .sx { color: #008000 } /* Literal.String.Other */\n",
       ".highlight .sr { color: #A45A77 } /* Literal.String.Regex */\n",
       ".highlight .s1 { color: #BA2121 } /* Literal.String.Single */\n",
       ".highlight .ss { color: #19177C } /* Literal.String.Symbol */\n",
       ".highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */\n",
       ".highlight .fm { color: #00F } /* Name.Function.Magic */\n",
       ".highlight .vc { color: #19177C } /* Name.Variable.Class */\n",
       ".highlight .vg { color: #19177C } /* Name.Variable.Global */\n",
       ".highlight .vi { color: #19177C } /* Name.Variable.Instance */\n",
       ".highlight .vm { color: #19177C } /* Name.Variable.Magic */\n",
       ".highlight .il { color: #666 } /* Literal.Number.Integer.Long */</style><div class=\"highlight\"><pre><span></span><span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"nn\">openmdao.api</span><span class=\"w\"> </span><span class=\"k\">as</span><span class=\"w\"> </span><span class=\"nn\">om</span>\n",
       "<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">openmdao.test_suite.components.paraboloid</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Paraboloid</span>\n",
       "\n",
       "<span class=\"n\">prob</span> <span class=\"o\">=</span> <span class=\"n\">om</span><span class=\"o\">.</span><span class=\"n\">Problem</span><span class=\"p\">()</span>\n",
       "\n",
       "<span class=\"n\">prob</span><span class=\"o\">.</span><span class=\"n\">model</span><span class=\"o\">.</span><span class=\"n\">add_subsystem</span><span class=\"p\">(</span><span class=\"s1\">&#39;comp&#39;</span><span class=\"p\">,</span> <span class=\"n\">Paraboloid</span><span class=\"p\">(),</span> <span class=\"n\">promotes</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"s1\">&#39;x&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;y&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;f_xy&#39;</span><span class=\"p\">])</span>\n",
       "<span class=\"n\">prob</span><span class=\"o\">.</span><span class=\"n\">model</span><span class=\"o\">.</span><span class=\"n\">add_design_var</span><span class=\"p\">(</span><span class=\"s1\">&#39;x&#39;</span><span class=\"p\">,</span> <span class=\"n\">lower</span><span class=\"o\">=</span><span class=\"mf\">0.0</span><span class=\"p\">,</span> <span class=\"n\">upper</span><span class=\"o\">=</span><span class=\"mf\">1.0</span><span class=\"p\">)</span>\n",
       "<span class=\"n\">prob</span><span class=\"o\">.</span><span class=\"n\">model</span><span class=\"o\">.</span><span class=\"n\">add_design_var</span><span class=\"p\">(</span><span class=\"s1\">&#39;y&#39;</span><span class=\"p\">,</span> <span class=\"n\">lower</span><span class=\"o\">=</span><span class=\"mf\">0.0</span><span class=\"p\">,</span> <span class=\"n\">upper</span><span class=\"o\">=</span><span class=\"mf\">1.0</span><span class=\"p\">)</span>\n",
       "<span class=\"n\">prob</span><span class=\"o\">.</span><span class=\"n\">model</span><span class=\"o\">.</span><span class=\"n\">add_objective</span><span class=\"p\">(</span><span class=\"s1\">&#39;f_xy&#39;</span><span class=\"p\">)</span>\n",
       "\n",
       "<span class=\"n\">prob</span><span class=\"o\">.</span><span class=\"n\">driver</span> <span class=\"o\">=</span> <span class=\"n\">om</span><span class=\"o\">.</span><span class=\"n\">DOEDriver</span><span class=\"p\">(</span><span class=\"n\">om</span><span class=\"o\">.</span><span class=\"n\">FullFactorialGenerator</span><span class=\"p\">(</span><span class=\"n\">levels</span><span class=\"o\">=</span><span class=\"mi\">3</span><span class=\"p\">))</span>\n",
       "<span class=\"n\">prob</span><span class=\"o\">.</span><span class=\"n\">driver</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"p\">[</span><span class=\"s1\">&#39;run_parallel&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"kc\">True</span>\n",
       "<span class=\"n\">prob</span><span class=\"o\">.</span><span class=\"n\">driver</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"p\">[</span><span class=\"s1\">&#39;procs_per_model&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"mi\">1</span>\n",
       "\n",
       "<span class=\"n\">prob</span><span class=\"o\">.</span><span class=\"n\">driver</span><span class=\"o\">.</span><span class=\"n\">add_recorder</span><span class=\"p\">(</span><span class=\"n\">om</span><span class=\"o\">.</span><span class=\"n\">SqliteRecorder</span><span class=\"p\">(</span><span class=\"s2\">&quot;doe_driver.sql&quot;</span><span class=\"p\">))</span>\n",
       "\n",
       "<span class=\"n\">prob</span><span class=\"o\">.</span><span class=\"n\">setup</span><span class=\"p\">()</span>\n",
       "<span class=\"n\">prob</span><span class=\"o\">.</span><span class=\"n\">run_driver</span><span class=\"p\">()</span>\n",
       "<span class=\"n\">prob</span><span class=\"o\">.</span><span class=\"n\">cleanup</span><span class=\"p\">()</span>\n",
       "\n",
       "<span class=\"c1\"># check recorded cases from each case file</span>\n",
       "<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">mpi4py</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">MPI</span>\n",
       "<span class=\"n\">rank</span> <span class=\"o\">=</span> <span class=\"n\">MPI</span><span class=\"o\">.</span><span class=\"n\">COMM_WORLD</span><span class=\"o\">.</span><span class=\"n\">rank</span>\n",
       "\n",
       "<span class=\"n\">filename</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;doe_driver.sql_</span><span class=\"si\">%d</span><span class=\"s2\">&quot;</span> <span class=\"o\">%</span> <span class=\"n\">rank</span>\n",
       "\n",
       "<span class=\"n\">cr</span> <span class=\"o\">=</span> <span class=\"n\">om</span><span class=\"o\">.</span><span class=\"n\">CaseReader</span><span class=\"p\">(</span><span class=\"n\">prob</span><span class=\"o\">.</span><span class=\"n\">get_outputs_dir</span><span class=\"p\">()</span> <span class=\"o\">/</span> <span class=\"n\">filename</span><span class=\"p\">)</span>\n",
       "<span class=\"n\">cases</span> <span class=\"o\">=</span> <span class=\"n\">cr</span><span class=\"o\">.</span><span class=\"n\">list_cases</span><span class=\"p\">(</span><span class=\"s1\">&#39;driver&#39;</span><span class=\"p\">,</span> <span class=\"n\">out_stream</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">)</span>\n",
       "<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">cases</span><span class=\"p\">)</span>\n",
       "\n",
       "<span class=\"n\">values</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n",
       "<span class=\"k\">for</span> <span class=\"n\">case</span> <span class=\"ow\">in</span> <span class=\"n\">cases</span><span class=\"p\">:</span>\n",
       "    <span class=\"n\">outputs</span> <span class=\"o\">=</span> <span class=\"n\">cr</span><span class=\"o\">.</span><span class=\"n\">get_case</span><span class=\"p\">(</span><span class=\"n\">case</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">outputs</span>\n",
       "    <span class=\"n\">values</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">((</span><span class=\"n\">outputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;x&#39;</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">item</span><span class=\"p\">(),</span> <span class=\"n\">outputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;y&#39;</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">item</span><span class=\"p\">(),</span> <span class=\"n\">outputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;f_xy&#39;</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">item</span><span class=\"p\">()))</span>\n",
       "\n",
       "<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s2\">&quot;</span><span class=\"se\">\\n</span><span class=\"s2\">&quot;</span><span class=\"o\">+</span><span class=\"s2\">&quot;</span><span class=\"se\">\\n</span><span class=\"s2\">&quot;</span><span class=\"o\">.</span><span class=\"n\">join</span><span class=\"p\">([</span><span class=\"s2\">&quot;x: </span><span class=\"si\">%5.2f</span><span class=\"s2\">, y: </span><span class=\"si\">%5.2f</span><span class=\"s2\">, f_xy: </span><span class=\"si\">%6.2f</span><span class=\"s2\">&quot;</span> <span class=\"o\">%</span> <span class=\"n\">xyf</span> <span class=\"k\">for</span> <span class=\"n\">xyf</span> <span class=\"ow\">in</span> <span class=\"n\">values</span><span class=\"p\">]))</span>\n",
       "\n",
       "<span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"nn\">numpy</span><span class=\"w\"> </span><span class=\"k\">as</span><span class=\"w\"> </span><span class=\"nn\">np</span>\n",
       "\n",
       "<span class=\"k\">assert</span><span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">cases</span><span class=\"p\">)</span> <span class=\"o\">==</span> <span class=\"mi\">3</span> <span class=\"k\">if</span> <span class=\"n\">rank</span> <span class=\"o\">==</span> <span class=\"mi\">0</span> <span class=\"k\">else</span> <span class=\"mi\">2</span><span class=\"p\">)</span>\n",
       "<span class=\"k\">if</span> <span class=\"n\">rank</span> <span class=\"o\">==</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n",
       "    <span class=\"n\">expected</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n",
       "        <span class=\"p\">{</span><span class=\"s1\">&#39;x&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">0.</span><span class=\"p\">]),</span> <span class=\"s1\">&#39;y&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">0.</span><span class=\"p\">]),</span> <span class=\"s1\">&#39;f_xy&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">22.00</span><span class=\"p\">])},</span>\n",
       "        <span class=\"p\">{</span><span class=\"s1\">&#39;x&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">.5</span><span class=\"p\">]),</span> <span class=\"s1\">&#39;y&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">.5</span><span class=\"p\">]),</span> <span class=\"s1\">&#39;f_xy&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">23.75</span><span class=\"p\">])},</span>\n",
       "        <span class=\"p\">{</span><span class=\"s1\">&#39;x&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">1.</span><span class=\"p\">]),</span> <span class=\"s1\">&#39;y&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">1.</span><span class=\"p\">]),</span> <span class=\"s1\">&#39;f_xy&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">27.00</span><span class=\"p\">])}]</span>\n",
       "<span class=\"k\">elif</span> <span class=\"n\">rank</span> <span class=\"o\">==</span> <span class=\"mi\">1</span><span class=\"p\">:</span>\n",
       "    <span class=\"n\">expected</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n",
       "        <span class=\"p\">{</span><span class=\"s1\">&#39;x&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">.5</span><span class=\"p\">]),</span> <span class=\"s1\">&#39;y&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">0.</span><span class=\"p\">]),</span> <span class=\"s1\">&#39;f_xy&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">19.25</span><span class=\"p\">])},</span>\n",
       "        <span class=\"p\">{</span><span class=\"s1\">&#39;x&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">1.</span><span class=\"p\">]),</span> <span class=\"s1\">&#39;y&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">.5</span><span class=\"p\">]),</span> <span class=\"s1\">&#39;f_xy&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">21.75</span><span class=\"p\">])}]</span>\n",
       "<span class=\"k\">elif</span> <span class=\"n\">rank</span> <span class=\"o\">==</span> <span class=\"mi\">2</span><span class=\"p\">:</span>\n",
       "    <span class=\"n\">expected</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n",
       "        <span class=\"p\">{</span><span class=\"s1\">&#39;x&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">1.</span><span class=\"p\">]),</span> <span class=\"s1\">&#39;y&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">0.</span><span class=\"p\">]),</span> <span class=\"s1\">&#39;f_xy&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">17.00</span><span class=\"p\">])},</span>\n",
       "        <span class=\"p\">{</span><span class=\"s1\">&#39;x&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">0.</span><span class=\"p\">]),</span> <span class=\"s1\">&#39;y&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">1.</span><span class=\"p\">]),</span> <span class=\"s1\">&#39;f_xy&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">31.00</span><span class=\"p\">])}]</span>\n",
       "<span class=\"k\">else</span><span class=\"p\">:</span>\n",
       "    <span class=\"n\">expected</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n",
       "        <span class=\"p\">{</span><span class=\"s1\">&#39;x&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">0.</span><span class=\"p\">]),</span> <span class=\"s1\">&#39;y&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">.5</span><span class=\"p\">]),</span> <span class=\"s1\">&#39;f_xy&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">26.25</span><span class=\"p\">])},</span>\n",
       "        <span class=\"p\">{</span><span class=\"s1\">&#39;x&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">.5</span><span class=\"p\">]),</span> <span class=\"s1\">&#39;y&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">1.</span><span class=\"p\">]),</span> <span class=\"s1\">&#39;f_xy&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">28.75</span><span class=\"p\">])}]</span>\n",
       "\n",
       "\n",
       "<span class=\"n\">exp_values</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n",
       "<span class=\"k\">for</span> <span class=\"n\">case</span> <span class=\"ow\">in</span> <span class=\"n\">expected</span><span class=\"p\">:</span>\n",
       "    <span class=\"n\">exp_values</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">((</span><span class=\"n\">case</span><span class=\"p\">[</span><span class=\"s1\">&#39;x&#39;</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">item</span><span class=\"p\">(),</span> <span class=\"n\">case</span><span class=\"p\">[</span><span class=\"s1\">&#39;y&#39;</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">item</span><span class=\"p\">(),</span> <span class=\"n\">case</span><span class=\"p\">[</span><span class=\"s1\">&#39;f_xy&#39;</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">item</span><span class=\"p\">()))</span>\n",
       "<span class=\"n\">expect_text</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;</span><span class=\"se\">\\n</span><span class=\"s2\">&quot;</span><span class=\"o\">+</span><span class=\"s2\">&quot;</span><span class=\"se\">\\n</span><span class=\"s2\">&quot;</span><span class=\"o\">.</span><span class=\"n\">join</span><span class=\"p\">([</span><span class=\"s2\">&quot;x: </span><span class=\"si\">%5.2f</span><span class=\"s2\">, y: </span><span class=\"si\">%5.2f</span><span class=\"s2\">, f_xy: </span><span class=\"si\">%6.2f</span><span class=\"s2\">&quot;</span> <span class=\"o\">%</span> <span class=\"n\">vals_i</span> <span class=\"k\">for</span> <span class=\"n\">vals_i</span> <span class=\"ow\">in</span> <span class=\"n\">exp_values</span><span class=\"p\">])</span>\n",
       "\n",
       "<span class=\"k\">assert</span><span class=\"p\">(</span><span class=\"s2\">&quot;</span><span class=\"se\">\\n</span><span class=\"s2\">&quot;</span><span class=\"o\">+</span><span class=\"s2\">&quot;</span><span class=\"se\">\\n</span><span class=\"s2\">&quot;</span><span class=\"o\">.</span><span class=\"n\">join</span><span class=\"p\">([</span><span class=\"s2\">&quot;x: </span><span class=\"si\">%5.2f</span><span class=\"s2\">, y: </span><span class=\"si\">%5.2f</span><span class=\"s2\">, f_xy: </span><span class=\"si\">%6.2f</span><span class=\"s2\">&quot;</span> <span class=\"o\">%</span> <span class=\"n\">xyf</span> <span class=\"k\">for</span> <span class=\"n\">xyf</span> <span class=\"ow\">in</span> <span class=\"n\">values</span><span class=\"p\">])</span> <span class=\"o\">==</span> <span class=\"n\">expect_text</span><span class=\"p\">)</span>\n",
       "</pre></div>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1790952511.087545] [runnervm8df0l:11390:0]        ib_iface.c:1269 UCX  ERROR mana_0: iface 0x55ea40256140 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",
      "[1790952511.087869] [runnervm8df0l:11390:0]      ucp_worker.c:1412 UCX  ERROR uct_iface_open(ud_verbs/mana_0:1) failed: Input/output error\n",
      "[1790952511.112051] [runnervm8df0l:11391:0]        ib_iface.c:1269 UCX  ERROR mana_0: iface 0x5635706555d0 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",
      "[1790952511.112423] [runnervm8df0l:11393:0]        ib_iface.c:1269 UCX  ERROR mana_0: iface 0x5652ddb0eb20 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",
      "[1790952511.112523] [runnervm8df0l:11392:0]        ib_iface.c:1269 UCX  ERROR mana_0: iface 0x55b1532671c0 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",
      "[1790952511.113348] [runnervm8df0l:11391:0]      ucp_worker.c:1412 UCX  ERROR uct_iface_open(ud_verbs/mana_0:1) failed: Input/output error\n",
      "[1790952511.113413] [runnervm8df0l:11393:0]      ucp_worker.c:1412 UCX  ERROR uct_iface_open(ud_verbs/mana_0:1) failed: Input/output error\n",
      "[1790952511.113636] [runnervm8df0l:11392:0]      ucp_worker.c:1412 UCX  ERROR uct_iface_open(ud_verbs/mana_0:1) failed: Input/output error\n",
      "Note: SqliteRecorder is running on multiple processors. Cases from rank 1 are being written to /home/runner/work/OpenMDAO/OpenMDAO/openmdao/docs/_executed_book/features/building_blocks/drivers/mpi_script_0_out/doe_driver.sql_1.\n",
      "Note: SqliteRecorder is running on multiple processors. Cases from rank 0 are being written to /home/runner/work/OpenMDAO/OpenMDAO/openmdao/docs/_executed_book/features/building_blocks/drivers/mpi_script_0_out/doe_driver.sql_0.\n",
      "Note: Metadata is being recorded separately as /home/runner/work/OpenMDAO/OpenMDAO/openmdao/docs/_executed_book/features/building_blocks/drivers/mpi_script_0_out/doe_driver.sql_meta.\n",
      "Note: SqliteRecorder is running on multiple processors. Cases from rank 3 are being written to /home/runner/work/OpenMDAO/OpenMDAO/openmdao/docs/_executed_book/features/building_blocks/drivers/mpi_script_0_out/doe_driver.sql_3.\n",
      "Note: SqliteRecorder is running on multiple processors. Cases from rank 2 are being written to /home/runner/work/OpenMDAO/OpenMDAO/openmdao/docs/_executed_book/features/building_blocks/drivers/mpi_script_0_out/doe_driver.sql_2.\n",
      "['rank0:DOEDriver_FullFactorial|0', 'rank0:DOEDriver_FullFactorial|1']\n",
      "\n",
      "x:  0.00, y:  0.50, f_xy:  26.25\n",
      "x:  0.50, y:  1.00, f_xy:  28.75\n",
      "['rank0:DOEDriver_FullFactorial|0', 'rank0:DOEDriver_FullFactorial|1']\n",
      "\n",
      "x:  0.50, y:  0.00, f_xy:  19.25\n",
      "x:  1.00, y:  0.50, f_xy:  21.75\n",
      "['rank0:DOEDriver_FullFactorial|0', 'rank0:DOEDriver_FullFactorial|1']\n",
      "\n",
      "x:  1.00, y:  0.00, f_xy:  17.00\n",
      "x:  0.00, y:  1.00, f_xy:  31.00\n",
      "['rank0:DOEDriver_FullFactorial|0', 'rank0:DOEDriver_FullFactorial|1', 'rank0:DOEDriver_FullFactorial|2']\n",
      "\n",
      "x:  0.00, y:  0.00, f_xy:  22.00\n",
      "x:  0.50, y:  0.50, f_xy:  23.75\n",
      "x:  1.00, y:  1.00, f_xy:  27.00\n",
      "\n"
     ]
    }
   ],
   "source": [
    "from openmdao.utils.notebook_utils import mpi_exec\n",
    "mpi_exec(4, 'mpi_script_0.py')"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "c2c8fb48",
   "metadata": {
    "papermill": {
     "duration": 0.015828,
     "end_time": "2026-10-02T14:48:33.650150+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:48:33.634322+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "## Running a DOE in Parallel with a Parallel Model\n",
    "\n",
    "If the model that is being subjected to the DOE is also parallel, then the total number of processors should reflect the model size as well as the desired concurrency.\n",
    "\n",
    "To illustrate this, we will demonstrate performing a DOE on a model based on the [ParallelGroup](../../core_features/working_with_groups/parallel_group.ipynb) example:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "b5cac794",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:48:33.655027Z",
     "iopub.status.busy": "2026-10-02T14:48:33.654860Z",
     "iopub.status.idle": "2026-10-02T14:48:33.658216Z",
     "shell.execute_reply": "2026-10-02T14:48:33.657456Z"
    },
    "papermill": {
     "duration": 0.006427,
     "end_time": "2026-10-02T14:48:33.658650+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:48:33.652223+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "\n",
    "class FanInGrouped(om.Group):\n",
    "    \"\"\"\n",
    "    Topology where two components in a Group feed a single component\n",
    "    outside of that Group.\n",
    "    \"\"\"\n",
    "\n",
    "    def __init__(self):\n",
    "        super().__init__()\n",
    "\n",
    "        self.set_input_defaults('x1', 1.0)\n",
    "        self.set_input_defaults('x2', 1.0)\n",
    "\n",
    "        self.sub = self.add_subsystem('sub', om.ParallelGroup(),\n",
    "                                      promotes_inputs=['x1', 'x2'])\n",
    "\n",
    "        self.sub.add_subsystem('c1', om.ExecComp(['y=-2.0*x']),\n",
    "                               promotes_inputs=[('x', 'x1')])\n",
    "        self.sub.add_subsystem('c2', om.ExecComp(['y=5.0*x']),\n",
    "                               promotes_inputs=[('x', 'x2')])\n",
    "\n",
    "        self.add_subsystem('c3', om.ExecComp(['y=3.0*x1+7.0*x2']))\n",
    "\n",
    "        self.connect(\"sub.c1.y\", \"c3.x1\")\n",
    "        self.connect(\"sub.c2.y\", \"c3.x2\")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "abc57c03",
   "metadata": {
    "papermill": {
     "duration": 0.001806,
     "end_time": "2026-10-02T14:48:33.662307+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:48:33.660501+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "In this case, the model itself requires two processors, so in order to run cases concurrently we need to allocate at least four processors in total. We can allocate as many processors as we have available, however the number of processors must be a multiple of the number of processors per model, which is 2 here. Regardless of how many processors we allocate, we need to tell the `DOEDriver` that the model needs 2 processors, which is done by specifying `options['procs_per_model']=2`. From this, the driver figures out how many models it can run in parallel, which in this case is also 2.\n",
    "\n",
    "The `SqliteRecorder` will record cases on the first two processors, which serve as the “root” processors for the parallel cases."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "c85fc5d1",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:48:33.666669Z",
     "iopub.status.busy": "2026-10-02T14:48:33.666546Z",
     "iopub.status.idle": "2026-10-02T14:48:33.670298Z",
     "shell.execute_reply": "2026-10-02T14:48:33.669619Z"
    },
    "papermill": {
     "duration": 0.00654,
     "end_time": "2026-10-02T14:48:33.670725+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:48:33.664185+00:00",
     "status": "completed"
    },
    "tags": [
     "remove-cell"
    ]
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Overwriting mpi_script_1.py\n"
     ]
    }
   ],
   "source": [
    "%%writefile mpi_script_1.py\n",
    "import numpy as np\n",
    "import openmdao.api as om\n",
    "\n",
    "\n",
    "class FanInGrouped(om.Group):\n",
    "    \"\"\"\n",
    "    Topology where two components in a Group feed a single component\n",
    "    outside of that Group.\n",
    "    \"\"\"\n",
    "\n",
    "    def __init__(self):\n",
    "        super().__init__()\n",
    "\n",
    "        self.set_input_defaults('x1', 1.0)\n",
    "        self.set_input_defaults('x2', 1.0)\n",
    "\n",
    "        self.sub = self.add_subsystem('sub', om.ParallelGroup(),\n",
    "                                      promotes_inputs=['x1', 'x2'])\n",
    "\n",
    "        self.sub.add_subsystem('c1', om.ExecComp(['y=-2.0*x']),\n",
    "                               promotes_inputs=[('x', 'x1')])\n",
    "        self.sub.add_subsystem('c2', om.ExecComp(['y=5.0*x']),\n",
    "                               promotes_inputs=[('x', 'x2')])\n",
    "\n",
    "        self.add_subsystem('c3', om.ExecComp(['y=3.0*x1+7.0*x2']))\n",
    "\n",
    "        self.connect(\"sub.c1.y\", \"c3.x1\")\n",
    "        self.connect(\"sub.c2.y\", \"c3.x2\")\n",
    "\n",
    "prob = om.Problem(FanInGrouped())\n",
    "\n",
    "prob.model.add_design_var('x1', lower=0.0, upper=1.0)\n",
    "prob.model.add_design_var('x2', lower=0.0, upper=1.0)\n",
    "prob.model.add_objective('c3.y')\n",
    "\n",
    "prob.driver = om.DOEDriver(om.FullFactorialGenerator(levels=3))\n",
    "prob.driver.add_recorder(om.SqliteRecorder(\"cases.sql\"))\n",
    "\n",
    "# the FanInGrouped model uses 2 processes, so we can run\n",
    "# two instances of the model at a time, each using 2 of our 4 procs\n",
    "prob.driver.options['run_parallel'] = True\n",
    "prob.driver.options['procs_per_model'] = procs_per_model = 2\n",
    "\n",
    "prob.setup()\n",
    "prob.run_driver()\n",
    "prob.cleanup()\n",
    "\n",
    "# a separate case file will be written by rank 0 of each parallel model\n",
    "# (the top two global ranks)\n",
    "rank = prob.comm.rank\n",
    "\n",
    "num_models = prob.comm.size // procs_per_model\n",
    "\n",
    "if rank < num_models:\n",
    "    filename = \"cases.sql_%d\" % rank\n",
    "\n",
    "    cr = om.CaseReader(prob.get_outputs_dir() / filename)\n",
    "    cases = cr.list_cases('driver', out_stream=None)\n",
    "\n",
    "    values = []\n",
    "    for case in cases:\n",
    "        outputs = cr.get_case(case).outputs\n",
    "        values.append((outputs['x1'].item(), outputs['x2'].item(), outputs['c3.y'].item()))\n",
    "\n",
    "    print(\"\\n\"+\"\\n\".join([\"x1: %5.2f, x2: %5.2f, c3.y: %6.2f\" % (x1, x2, y) for x1, x2, y in values]))\n",
    "if rank == 0:\n",
    "    expected = [\n",
    "            {'x1': np.array([0.]), 'x2': np.array([0.]), 'c3.y': np.array([0.00])},\n",
    "            {'x1': np.array([1.]), 'x2': np.array([0.]), 'c3.y': np.array([-6.00])},\n",
    "            {'x1': np.array([.5]), 'x2': np.array([.5]), 'c3.y': np.array([14.50])},\n",
    "            {'x1': np.array([0.]), 'x2': np.array([1.]), 'c3.y': np.array([35.00])},\n",
    "            {'x1': np.array([1.]), 'x2': np.array([1.]), 'c3.y': np.array([29.00])}]\n",
    "elif rank == 1:\n",
    "    expected = [\n",
    "            {'x1': np.array([.5]), 'x2': np.array([0.]), 'c3.y': np.array([-3.00])},\n",
    "            {'x1': np.array([0.]), 'x2': np.array([.5]), 'c3.y': np.array([17.50])},\n",
    "            {'x1': np.array([1.]), 'x2': np.array([.5]), 'c3.y': np.array([11.50])},\n",
    "            {'x1': np.array([.5]), 'x2': np.array([1.]), 'c3.y': np.array([32.00])}]\n",
    "\n",
    "if rank < 2:\n",
    "    exp_values = []\n",
    "    for idx, case in enumerate(expected):\n",
    "        exp_values.append((case['x1'].item(), case['x2'].item(), case['c3.y'].item()))\n",
    "\n",
    "    expect_text = \"\\n\"+\"\\n\".join([\n",
    "        \"x1: %5.2f, x2: %5.2f, c3.y: %6.2f\" % vals_i for vals_i in exp_values])\n",
    "    assert(\"\\n\"+\"\\n\".join([\"x1: %5.2f, x2: %5.2f, c3.y: %6.2f\" % (x1, x2, y) for x1, x2, y in values]) == expect_text)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "eb5afe76",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:48:33.675154Z",
     "iopub.status.busy": "2026-10-02T14:48:33.675011Z",
     "iopub.status.idle": "2026-10-02T14:48:38.257952Z",
     "shell.execute_reply": "2026-10-02T14:48:38.257209Z"
    },
    "papermill": {
     "duration": 4.585776,
     "end_time": "2026-10-02T14:48:38.258433+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:48:33.672657+00:00",
     "status": "completed"
    },
    "tags": [
     "remove-input"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div class=\"admonition note\"><p class=\"admonition-title\">Note</p><p>This feature requires MPI, and may not be able to be run on Colab or Binder.</p></div>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<p>The following script is executed using <code>mpiexec -n 4 mpi_script_1.py</code>:</p><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",
       ".highlight .hll { background-color: #ffffcc }\n",
       ".highlight { background: #f8f8f8; }\n",
       ".highlight .c { color: #3D7B7B; font-style: italic } /* Comment */\n",
       ".highlight .err { border: 1px solid #F00 } /* Error */\n",
       ".highlight .k { color: #008000; font-weight: bold } /* Keyword */\n",
       ".highlight .o { color: #666 } /* Operator */\n",
       ".highlight .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */\n",
       ".highlight .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */\n",
       ".highlight .cp { color: #9C6500 } /* Comment.Preproc */\n",
       ".highlight .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */\n",
       ".highlight .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */\n",
       ".highlight .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */\n",
       ".highlight .gd { color: #A00000 } /* Generic.Deleted */\n",
       ".highlight .ge { font-style: italic } /* Generic.Emph */\n",
       ".highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */\n",
       ".highlight .gr { color: #E40000 } /* Generic.Error */\n",
       ".highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n",
       ".highlight .gi { color: #008400 } /* Generic.Inserted */\n",
       ".highlight .go { color: #717171 } /* Generic.Output */\n",
       ".highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */\n",
       ".highlight .gs { font-weight: bold } /* Generic.Strong */\n",
       ".highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n",
       ".highlight .gt { color: #04D } /* Generic.Traceback */\n",
       ".highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */\n",
       ".highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */\n",
       ".highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */\n",
       ".highlight .kp { color: #008000 } /* Keyword.Pseudo */\n",
       ".highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */\n",
       ".highlight .kt { color: #B00040 } /* Keyword.Type */\n",
       ".highlight .m { color: #666 } /* Literal.Number */\n",
       ".highlight .s { color: #BA2121 } /* Literal.String */\n",
       ".highlight .na { color: #687822 } /* Name.Attribute */\n",
       ".highlight .nb { color: #008000 } /* Name.Builtin */\n",
       ".highlight .nc { color: #00F; font-weight: bold } /* Name.Class */\n",
       ".highlight .no { color: #800 } /* Name.Constant */\n",
       ".highlight .nd { color: #A2F } /* Name.Decorator */\n",
       ".highlight .ni { color: #717171; font-weight: bold } /* Name.Entity */\n",
       ".highlight .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */\n",
       ".highlight .nf { color: #00F } /* Name.Function */\n",
       ".highlight .nl { color: #767600 } /* Name.Label */\n",
       ".highlight .nn { color: #00F; font-weight: bold } /* Name.Namespace */\n",
       ".highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */\n",
       ".highlight .nv { color: #19177C } /* Name.Variable */\n",
       ".highlight .ow { color: #A2F; font-weight: bold } /* Operator.Word */\n",
       ".highlight .w { color: #BBB } /* Text.Whitespace */\n",
       ".highlight .mb { color: #666 } /* Literal.Number.Bin */\n",
       ".highlight .mf { color: #666 } /* Literal.Number.Float */\n",
       ".highlight .mh { color: #666 } /* Literal.Number.Hex */\n",
       ".highlight .mi { color: #666 } /* Literal.Number.Integer */\n",
       ".highlight .mo { color: #666 } /* Literal.Number.Oct */\n",
       ".highlight .sa { color: #BA2121 } /* Literal.String.Affix */\n",
       ".highlight .sb { color: #BA2121 } /* Literal.String.Backtick */\n",
       ".highlight .sc { color: #BA2121 } /* Literal.String.Char */\n",
       ".highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */\n",
       ".highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */\n",
       ".highlight .s2 { color: #BA2121 } /* Literal.String.Double */\n",
       ".highlight .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */\n",
       ".highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */\n",
       ".highlight .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */\n",
       ".highlight .sx { color: #008000 } /* Literal.String.Other */\n",
       ".highlight .sr { color: #A45A77 } /* Literal.String.Regex */\n",
       ".highlight .s1 { color: #BA2121 } /* Literal.String.Single */\n",
       ".highlight .ss { color: #19177C } /* Literal.String.Symbol */\n",
       ".highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */\n",
       ".highlight .fm { color: #00F } /* Name.Function.Magic */\n",
       ".highlight .vc { color: #19177C } /* Name.Variable.Class */\n",
       ".highlight .vg { color: #19177C } /* Name.Variable.Global */\n",
       ".highlight .vi { color: #19177C } /* Name.Variable.Instance */\n",
       ".highlight .vm { color: #19177C } /* Name.Variable.Magic */\n",
       ".highlight .il { color: #666 } /* Literal.Number.Integer.Long */</style><div class=\"highlight\"><pre><span></span><span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"nn\">numpy</span><span class=\"w\"> </span><span class=\"k\">as</span><span class=\"w\"> </span><span class=\"nn\">np</span>\n",
       "<span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"nn\">openmdao.api</span><span class=\"w\"> </span><span class=\"k\">as</span><span class=\"w\"> </span><span class=\"nn\">om</span>\n",
       "\n",
       "\n",
       "<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">FanInGrouped</span><span class=\"p\">(</span><span class=\"n\">om</span><span class=\"o\">.</span><span class=\"n\">Group</span><span class=\"p\">):</span>\n",
       "<span class=\"w\">    </span><span class=\"sd\">&quot;&quot;&quot;</span>\n",
       "<span class=\"sd\">    Topology where two components in a Group feed a single component</span>\n",
       "<span class=\"sd\">    outside of that Group.</span>\n",
       "<span class=\"sd\">    &quot;&quot;&quot;</span>\n",
       "\n",
       "    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n",
       "        <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"fm\">__init__</span><span class=\"p\">()</span>\n",
       "\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">set_input_defaults</span><span class=\"p\">(</span><span class=\"s1\">&#39;x1&#39;</span><span class=\"p\">,</span> <span class=\"mf\">1.0</span><span class=\"p\">)</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">set_input_defaults</span><span class=\"p\">(</span><span class=\"s1\">&#39;x2&#39;</span><span class=\"p\">,</span> <span class=\"mf\">1.0</span><span class=\"p\">)</span>\n",
       "\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">sub</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_subsystem</span><span class=\"p\">(</span><span class=\"s1\">&#39;sub&#39;</span><span class=\"p\">,</span> <span class=\"n\">om</span><span class=\"o\">.</span><span class=\"n\">ParallelGroup</span><span class=\"p\">(),</span>\n",
       "                                      <span class=\"n\">promotes_inputs</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"s1\">&#39;x1&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;x2&#39;</span><span class=\"p\">])</span>\n",
       "\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">sub</span><span class=\"o\">.</span><span class=\"n\">add_subsystem</span><span class=\"p\">(</span><span class=\"s1\">&#39;c1&#39;</span><span class=\"p\">,</span> <span class=\"n\">om</span><span class=\"o\">.</span><span class=\"n\">ExecComp</span><span class=\"p\">([</span><span class=\"s1\">&#39;y=-2.0*x&#39;</span><span class=\"p\">]),</span>\n",
       "                               <span class=\"n\">promotes_inputs</span><span class=\"o\">=</span><span class=\"p\">[(</span><span class=\"s1\">&#39;x&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;x1&#39;</span><span class=\"p\">)])</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">sub</span><span class=\"o\">.</span><span class=\"n\">add_subsystem</span><span class=\"p\">(</span><span class=\"s1\">&#39;c2&#39;</span><span class=\"p\">,</span> <span class=\"n\">om</span><span class=\"o\">.</span><span class=\"n\">ExecComp</span><span class=\"p\">([</span><span class=\"s1\">&#39;y=5.0*x&#39;</span><span class=\"p\">]),</span>\n",
       "                               <span class=\"n\">promotes_inputs</span><span class=\"o\">=</span><span class=\"p\">[(</span><span class=\"s1\">&#39;x&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;x2&#39;</span><span class=\"p\">)])</span>\n",
       "\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_subsystem</span><span class=\"p\">(</span><span class=\"s1\">&#39;c3&#39;</span><span class=\"p\">,</span> <span class=\"n\">om</span><span class=\"o\">.</span><span class=\"n\">ExecComp</span><span class=\"p\">([</span><span class=\"s1\">&#39;y=3.0*x1+7.0*x2&#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=\"s2\">&quot;sub.c1.y&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;c3.x1&quot;</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=\"s2\">&quot;sub.c2.y&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;c3.x2&quot;</span><span class=\"p\">)</span>\n",
       "\n",
       "<span class=\"n\">prob</span> <span class=\"o\">=</span> <span class=\"n\">om</span><span class=\"o\">.</span><span class=\"n\">Problem</span><span class=\"p\">(</span><span class=\"n\">FanInGrouped</span><span class=\"p\">())</span>\n",
       "\n",
       "<span class=\"n\">prob</span><span class=\"o\">.</span><span class=\"n\">model</span><span class=\"o\">.</span><span class=\"n\">add_design_var</span><span class=\"p\">(</span><span class=\"s1\">&#39;x1&#39;</span><span class=\"p\">,</span> <span class=\"n\">lower</span><span class=\"o\">=</span><span class=\"mf\">0.0</span><span class=\"p\">,</span> <span class=\"n\">upper</span><span class=\"o\">=</span><span class=\"mf\">1.0</span><span class=\"p\">)</span>\n",
       "<span class=\"n\">prob</span><span class=\"o\">.</span><span class=\"n\">model</span><span class=\"o\">.</span><span class=\"n\">add_design_var</span><span class=\"p\">(</span><span class=\"s1\">&#39;x2&#39;</span><span class=\"p\">,</span> <span class=\"n\">lower</span><span class=\"o\">=</span><span class=\"mf\">0.0</span><span class=\"p\">,</span> <span class=\"n\">upper</span><span class=\"o\">=</span><span class=\"mf\">1.0</span><span class=\"p\">)</span>\n",
       "<span class=\"n\">prob</span><span class=\"o\">.</span><span class=\"n\">model</span><span class=\"o\">.</span><span class=\"n\">add_objective</span><span class=\"p\">(</span><span class=\"s1\">&#39;c3.y&#39;</span><span class=\"p\">)</span>\n",
       "\n",
       "<span class=\"n\">prob</span><span class=\"o\">.</span><span class=\"n\">driver</span> <span class=\"o\">=</span> <span class=\"n\">om</span><span class=\"o\">.</span><span class=\"n\">DOEDriver</span><span class=\"p\">(</span><span class=\"n\">om</span><span class=\"o\">.</span><span class=\"n\">FullFactorialGenerator</span><span class=\"p\">(</span><span class=\"n\">levels</span><span class=\"o\">=</span><span class=\"mi\">3</span><span class=\"p\">))</span>\n",
       "<span class=\"n\">prob</span><span class=\"o\">.</span><span class=\"n\">driver</span><span class=\"o\">.</span><span class=\"n\">add_recorder</span><span class=\"p\">(</span><span class=\"n\">om</span><span class=\"o\">.</span><span class=\"n\">SqliteRecorder</span><span class=\"p\">(</span><span class=\"s2\">&quot;cases.sql&quot;</span><span class=\"p\">))</span>\n",
       "\n",
       "<span class=\"c1\"># the FanInGrouped model uses 2 processes, so we can run</span>\n",
       "<span class=\"c1\"># two instances of the model at a time, each using 2 of our 4 procs</span>\n",
       "<span class=\"n\">prob</span><span class=\"o\">.</span><span class=\"n\">driver</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"p\">[</span><span class=\"s1\">&#39;run_parallel&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"kc\">True</span>\n",
       "<span class=\"n\">prob</span><span class=\"o\">.</span><span class=\"n\">driver</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"p\">[</span><span class=\"s1\">&#39;procs_per_model&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">procs_per_model</span> <span class=\"o\">=</span> <span class=\"mi\">2</span>\n",
       "\n",
       "<span class=\"n\">prob</span><span class=\"o\">.</span><span class=\"n\">setup</span><span class=\"p\">()</span>\n",
       "<span class=\"n\">prob</span><span class=\"o\">.</span><span class=\"n\">run_driver</span><span class=\"p\">()</span>\n",
       "<span class=\"n\">prob</span><span class=\"o\">.</span><span class=\"n\">cleanup</span><span class=\"p\">()</span>\n",
       "\n",
       "<span class=\"c1\"># a separate case file will be written by rank 0 of each parallel model</span>\n",
       "<span class=\"c1\"># (the top two global ranks)</span>\n",
       "<span class=\"n\">rank</span> <span class=\"o\">=</span> <span class=\"n\">prob</span><span class=\"o\">.</span><span class=\"n\">comm</span><span class=\"o\">.</span><span class=\"n\">rank</span>\n",
       "\n",
       "<span class=\"n\">num_models</span> <span class=\"o\">=</span> <span class=\"n\">prob</span><span class=\"o\">.</span><span class=\"n\">comm</span><span class=\"o\">.</span><span class=\"n\">size</span> <span class=\"o\">//</span> <span class=\"n\">procs_per_model</span>\n",
       "\n",
       "<span class=\"k\">if</span> <span class=\"n\">rank</span> <span class=\"o\">&lt;</span> <span class=\"n\">num_models</span><span class=\"p\">:</span>\n",
       "    <span class=\"n\">filename</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;cases.sql_</span><span class=\"si\">%d</span><span class=\"s2\">&quot;</span> <span class=\"o\">%</span> <span class=\"n\">rank</span>\n",
       "\n",
       "    <span class=\"n\">cr</span> <span class=\"o\">=</span> <span class=\"n\">om</span><span class=\"o\">.</span><span class=\"n\">CaseReader</span><span class=\"p\">(</span><span class=\"n\">prob</span><span class=\"o\">.</span><span class=\"n\">get_outputs_dir</span><span class=\"p\">()</span> <span class=\"o\">/</span> <span class=\"n\">filename</span><span class=\"p\">)</span>\n",
       "    <span class=\"n\">cases</span> <span class=\"o\">=</span> <span class=\"n\">cr</span><span class=\"o\">.</span><span class=\"n\">list_cases</span><span class=\"p\">(</span><span class=\"s1\">&#39;driver&#39;</span><span class=\"p\">,</span> <span class=\"n\">out_stream</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">)</span>\n",
       "\n",
       "    <span class=\"n\">values</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n",
       "    <span class=\"k\">for</span> <span class=\"n\">case</span> <span class=\"ow\">in</span> <span class=\"n\">cases</span><span class=\"p\">:</span>\n",
       "        <span class=\"n\">outputs</span> <span class=\"o\">=</span> <span class=\"n\">cr</span><span class=\"o\">.</span><span class=\"n\">get_case</span><span class=\"p\">(</span><span class=\"n\">case</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">outputs</span>\n",
       "        <span class=\"n\">values</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">((</span><span class=\"n\">outputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;x1&#39;</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">item</span><span class=\"p\">(),</span> <span class=\"n\">outputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;x2&#39;</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">item</span><span class=\"p\">(),</span> <span class=\"n\">outputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;c3.y&#39;</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">item</span><span class=\"p\">()))</span>\n",
       "\n",
       "    <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s2\">&quot;</span><span class=\"se\">\\n</span><span class=\"s2\">&quot;</span><span class=\"o\">+</span><span class=\"s2\">&quot;</span><span class=\"se\">\\n</span><span class=\"s2\">&quot;</span><span class=\"o\">.</span><span class=\"n\">join</span><span class=\"p\">([</span><span class=\"s2\">&quot;x1: </span><span class=\"si\">%5.2f</span><span class=\"s2\">, x2: </span><span class=\"si\">%5.2f</span><span class=\"s2\">, c3.y: </span><span class=\"si\">%6.2f</span><span class=\"s2\">&quot;</span> <span class=\"o\">%</span> <span class=\"p\">(</span><span class=\"n\">x1</span><span class=\"p\">,</span> <span class=\"n\">x2</span><span class=\"p\">,</span> <span class=\"n\">y</span><span class=\"p\">)</span> <span class=\"k\">for</span> <span class=\"n\">x1</span><span class=\"p\">,</span> <span class=\"n\">x2</span><span class=\"p\">,</span> <span class=\"n\">y</span> <span class=\"ow\">in</span> <span class=\"n\">values</span><span class=\"p\">]))</span>\n",
       "<span class=\"k\">if</span> <span class=\"n\">rank</span> <span class=\"o\">==</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n",
       "    <span class=\"n\">expected</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n",
       "            <span class=\"p\">{</span><span class=\"s1\">&#39;x1&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">0.</span><span class=\"p\">]),</span> <span class=\"s1\">&#39;x2&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">0.</span><span class=\"p\">]),</span> <span class=\"s1\">&#39;c3.y&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">0.00</span><span class=\"p\">])},</span>\n",
       "            <span class=\"p\">{</span><span class=\"s1\">&#39;x1&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">1.</span><span class=\"p\">]),</span> <span class=\"s1\">&#39;x2&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">0.</span><span class=\"p\">]),</span> <span class=\"s1\">&#39;c3.y&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"o\">-</span><span class=\"mf\">6.00</span><span class=\"p\">])},</span>\n",
       "            <span class=\"p\">{</span><span class=\"s1\">&#39;x1&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">.5</span><span class=\"p\">]),</span> <span class=\"s1\">&#39;x2&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">.5</span><span class=\"p\">]),</span> <span class=\"s1\">&#39;c3.y&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">14.50</span><span class=\"p\">])},</span>\n",
       "            <span class=\"p\">{</span><span class=\"s1\">&#39;x1&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">0.</span><span class=\"p\">]),</span> <span class=\"s1\">&#39;x2&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">1.</span><span class=\"p\">]),</span> <span class=\"s1\">&#39;c3.y&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">35.00</span><span class=\"p\">])},</span>\n",
       "            <span class=\"p\">{</span><span class=\"s1\">&#39;x1&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">1.</span><span class=\"p\">]),</span> <span class=\"s1\">&#39;x2&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">1.</span><span class=\"p\">]),</span> <span class=\"s1\">&#39;c3.y&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">29.00</span><span class=\"p\">])}]</span>\n",
       "<span class=\"k\">elif</span> <span class=\"n\">rank</span> <span class=\"o\">==</span> <span class=\"mi\">1</span><span class=\"p\">:</span>\n",
       "    <span class=\"n\">expected</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n",
       "            <span class=\"p\">{</span><span class=\"s1\">&#39;x1&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">.5</span><span class=\"p\">]),</span> <span class=\"s1\">&#39;x2&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">0.</span><span class=\"p\">]),</span> <span class=\"s1\">&#39;c3.y&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"o\">-</span><span class=\"mf\">3.00</span><span class=\"p\">])},</span>\n",
       "            <span class=\"p\">{</span><span class=\"s1\">&#39;x1&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">0.</span><span class=\"p\">]),</span> <span class=\"s1\">&#39;x2&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">.5</span><span class=\"p\">]),</span> <span class=\"s1\">&#39;c3.y&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">17.50</span><span class=\"p\">])},</span>\n",
       "            <span class=\"p\">{</span><span class=\"s1\">&#39;x1&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">1.</span><span class=\"p\">]),</span> <span class=\"s1\">&#39;x2&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">.5</span><span class=\"p\">]),</span> <span class=\"s1\">&#39;c3.y&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">11.50</span><span class=\"p\">])},</span>\n",
       "            <span class=\"p\">{</span><span class=\"s1\">&#39;x1&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">.5</span><span class=\"p\">]),</span> <span class=\"s1\">&#39;x2&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">1.</span><span class=\"p\">]),</span> <span class=\"s1\">&#39;c3.y&#39;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mf\">32.00</span><span class=\"p\">])}]</span>\n",
       "\n",
       "<span class=\"k\">if</span> <span class=\"n\">rank</span> <span class=\"o\">&lt;</span> <span class=\"mi\">2</span><span class=\"p\">:</span>\n",
       "    <span class=\"n\">exp_values</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n",
       "    <span class=\"k\">for</span> <span class=\"n\">idx</span><span class=\"p\">,</span> <span class=\"n\">case</span> <span class=\"ow\">in</span> <span class=\"nb\">enumerate</span><span class=\"p\">(</span><span class=\"n\">expected</span><span class=\"p\">):</span>\n",
       "        <span class=\"n\">exp_values</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">((</span><span class=\"n\">case</span><span class=\"p\">[</span><span class=\"s1\">&#39;x1&#39;</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">item</span><span class=\"p\">(),</span> <span class=\"n\">case</span><span class=\"p\">[</span><span class=\"s1\">&#39;x2&#39;</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">item</span><span class=\"p\">(),</span> <span class=\"n\">case</span><span class=\"p\">[</span><span class=\"s1\">&#39;c3.y&#39;</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">item</span><span class=\"p\">()))</span>\n",
       "\n",
       "    <span class=\"n\">expect_text</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;</span><span class=\"se\">\\n</span><span class=\"s2\">&quot;</span><span class=\"o\">+</span><span class=\"s2\">&quot;</span><span class=\"se\">\\n</span><span class=\"s2\">&quot;</span><span class=\"o\">.</span><span class=\"n\">join</span><span class=\"p\">([</span>\n",
       "        <span class=\"s2\">&quot;x1: </span><span class=\"si\">%5.2f</span><span class=\"s2\">, x2: </span><span class=\"si\">%5.2f</span><span class=\"s2\">, c3.y: </span><span class=\"si\">%6.2f</span><span class=\"s2\">&quot;</span> <span class=\"o\">%</span> <span class=\"n\">vals_i</span> <span class=\"k\">for</span> <span class=\"n\">vals_i</span> <span class=\"ow\">in</span> <span class=\"n\">exp_values</span><span class=\"p\">])</span>\n",
       "    <span class=\"k\">assert</span><span class=\"p\">(</span><span class=\"s2\">&quot;</span><span class=\"se\">\\n</span><span class=\"s2\">&quot;</span><span class=\"o\">+</span><span class=\"s2\">&quot;</span><span class=\"se\">\\n</span><span class=\"s2\">&quot;</span><span class=\"o\">.</span><span class=\"n\">join</span><span class=\"p\">([</span><span class=\"s2\">&quot;x1: </span><span class=\"si\">%5.2f</span><span class=\"s2\">, x2: </span><span class=\"si\">%5.2f</span><span class=\"s2\">, c3.y: </span><span class=\"si\">%6.2f</span><span class=\"s2\">&quot;</span> <span class=\"o\">%</span> <span class=\"p\">(</span><span class=\"n\">x1</span><span class=\"p\">,</span> <span class=\"n\">x2</span><span class=\"p\">,</span> <span class=\"n\">y</span><span class=\"p\">)</span> <span class=\"k\">for</span> <span class=\"n\">x1</span><span class=\"p\">,</span> <span class=\"n\">x2</span><span class=\"p\">,</span> <span class=\"n\">y</span> <span class=\"ow\">in</span> <span class=\"n\">values</span><span class=\"p\">])</span> <span class=\"o\">==</span> <span class=\"n\">expect_text</span><span class=\"p\">)</span>\n",
       "</pre></div>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1790952515.400214] [runnervm8df0l:11416:0]        ib_iface.c:1269 UCX  ERROR mana_0: iface 0x55e009da6810 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",
      "[1790952515.400319] [runnervm8df0l:11413:0]        ib_iface.c:1269 UCX  ERROR mana_0: iface 0x55898ff44fe0 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",
      "[1790952515.400419] [runnervm8df0l:11414:0]        ib_iface.c:1269 UCX  ERROR mana_0: iface 0x559aa3b11420 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",
      "[1790952515.400508] [runnervm8df0l:11415:0]        ib_iface.c:1269 UCX  ERROR mana_0: iface 0x5559c3ea3050 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",
      "[1790952515.401223] [runnervm8df0l:11416:0]      ucp_worker.c:1412 UCX  ERROR uct_iface_open(ud_verbs/mana_0:1) failed: Input/output error\n",
      "[1790952515.401295] [runnervm8df0l:11413:0]      ucp_worker.c:1412 UCX  ERROR uct_iface_open(ud_verbs/mana_0:1) failed: Input/output error\n",
      "[1790952515.401378] [runnervm8df0l:11414:0]      ucp_worker.c:1412 UCX  ERROR uct_iface_open(ud_verbs/mana_0:1) failed: Input/output error\n",
      "[1790952515.401436] [runnervm8df0l:11415:0]      ucp_worker.c:1412 UCX  ERROR uct_iface_open(ud_verbs/mana_0:1) failed: Input/output error\n",
      "Note: SqliteRecorder is running on multiple processors. Cases from rank 1 are being written to /home/runner/work/OpenMDAO/OpenMDAO/openmdao/docs/_executed_book/features/building_blocks/drivers/mpi_script_1_out/cases.sql_1.\n",
      "Note: SqliteRecorder is running on multiple processors. Cases from rank 0 are being written to /home/runner/work/OpenMDAO/OpenMDAO/openmdao/docs/_executed_book/features/building_blocks/drivers/mpi_script_1_out/cases.sql_0.\n",
      "Note: Metadata is being recorded separately as /home/runner/work/OpenMDAO/OpenMDAO/openmdao/docs/_executed_book/features/building_blocks/drivers/mpi_script_1_out/cases.sql_meta.\n",
      "\n",
      "x1:  0.50, x2:  0.00, c3.y:  -3.00\n",
      "x1:  0.00, x2:  0.50, c3.y:  17.50\n",
      "x1:  1.00, x2:  0.50, c3.y:  11.50\n",
      "x1:  0.50, x2:  1.00, c3.y:  32.00\n",
      "\n",
      "x1:  0.00, x2:  0.00, c3.y:   0.00\n",
      "x1:  1.00, x2:  0.00, c3.y:  -6.00\n",
      "x1:  0.50, x2:  0.50, c3.y:  14.50\n",
      "x1:  0.00, x2:  1.00, c3.y:  35.00\n",
      "x1:  1.00, x2:  1.00, c3.y:  29.00\n",
      "\n"
     ]
    }
   ],
   "source": [
    "from openmdao.utils.notebook_utils import mpi_exec\n",
    "mpi_exec(4, 'mpi_script_1.py')"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "3087be29",
   "metadata": {
    "papermill": {
     "duration": 0.002248,
     "end_time": "2026-10-02T14:48:38.263414+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:48:38.261166+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "## Using Prepared Cases\n",
    "\n",
    "If you have a previously generated set of cases that you want to run using `DOEDriver`, there are a couple of ways to do that. The first is to provide those inputs via an external file in the CSV (comma separated values) format. The file should be organized with one column per design variable, with the first row containing the names of the design variables. The following example demonstrates how to use such a file to run a DOE using the `CSVGenerator`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "a2adf228",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:48:38.370029Z",
     "iopub.status.busy": "2026-10-02T14:48:38.369819Z",
     "iopub.status.idle": "2026-10-02T14:48:38.375273Z",
     "shell.execute_reply": "2026-10-02T14:48:38.374743Z"
    },
    "papermill": {
     "duration": 0.110081,
     "end_time": "2026-10-02T14:48:38.375752+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:48:38.265671+00:00",
     "status": "completed"
    },
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "# This cell creates a file called saved_cases.csv.\n",
    "\n",
    "import json\n",
    "import numpy as np\n",
    "\n",
    "expected_csv = '\\n'.join([\n",
    "    \" x ,   y\",\n",
    "    \"0.0,  0.0\",\n",
    "    \"0.5,  0.0\",\n",
    "    \"1.0,  0.0\",\n",
    "    \"0.0,  0.5\",\n",
    "    \"0.5,  0.5\",\n",
    "    \"1.0,  0.5\",\n",
    "    \"0.0,  1.0\",\n",
    "    \"0.5,  1.0\",\n",
    "    \"1.0,  1.0\",\n",
    "])\n",
    "\n",
    "with open('saved_cases.csv', 'w') as f:\n",
    "    f.write(expected_csv)\n",
    "\n",
    "expected = [\n",
    "    {'x': np.array([0.]), 'y': np.array([0.]), 'f_xy': np.array([22.00])},\n",
    "    {'x': np.array([.5]), 'y': np.array([0.]), 'f_xy': np.array([19.25])},\n",
    "    {'x': np.array([1.]), 'y': np.array([0.]), 'f_xy': np.array([17.00])},\n",
    "\n",
    "    {'x': np.array([0.]), 'y': np.array([.5]), 'f_xy': np.array([26.25])},\n",
    "    {'x': np.array([.5]), 'y': np.array([.5]), 'f_xy': np.array([23.75])},\n",
    "    {'x': np.array([1.]), 'y': np.array([.5]), 'f_xy': np.array([21.75])},\n",
    "\n",
    "    {'x': np.array([0.]), 'y': np.array([1.]), 'f_xy': np.array([31.00])},\n",
    "    {'x': np.array([.5]), 'y': np.array([1.]), 'f_xy': np.array([28.75])},\n",
    "    {'x': np.array([1.]), 'y': np.array([1.]), 'f_xy': np.array([27.00])},\n",
    "]\n",
    "\n",
    "values = []\n",
    "cases = []\n",
    "\n",
    "for case in expected:\n",
    "    values.append((case['x'].item(), case['y'].item(), case['f_xy'].item()))\n",
    "    # converting ndarray to list enables JSON serialization\n",
    "    cases.append((('x', list(case['x'])), ('y', list(case['y']))))\n",
    "\n",
    "expected_text = \"\\n\".join([\n",
    "    \"x: %5.2f, y: %5.2f, f_xy: %6.2f\" % vals_i for vals_i in values\n",
    "])\n",
    "\n",
    "expected_json = json.dumps(cases).replace(']]],', ']]],\\n')\n",
    "with open('cases.json', 'w') as f:\n",
    "    f.write(expected_json)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "e3cd8578",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:48:38.381135Z",
     "iopub.status.busy": "2026-10-02T14:48:38.380981Z",
     "iopub.status.idle": "2026-10-02T14:48:38.385797Z",
     "shell.execute_reply": "2026-10-02T14:48:38.385076Z"
    },
    "papermill": {
     "duration": 0.008353,
     "end_time": "2026-10-02T14:48:38.386320+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:48:38.377967+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " x ,   y\n",
      "0.0,  0.0\n",
      "0.5,  0.0\n",
      "1.0,  0.0\n",
      "0.0,  0.5\n",
      "0.5,  0.5\n",
      "1.0,  0.5\n",
      "0.0,  1.0\n",
      "0.5,  1.0\n",
      "1.0,  1.0\n"
     ]
    }
   ],
   "source": [
    "import openmdao.api as om\n",
    "from openmdao.test_suite.components.paraboloid import Paraboloid\n",
    "\n",
    "prob = om.Problem()\n",
    "model = prob.model\n",
    "\n",
    "model.add_subsystem('comp', Paraboloid(), promotes=['x', 'y', 'f_xy'])\n",
    "\n",
    "model.add_design_var('x', lower=0.0, upper=1.0)\n",
    "model.add_design_var('y', lower=0.0, upper=1.0)\n",
    "model.add_objective('f_xy')\n",
    "\n",
    "prob.setup()\n",
    "\n",
    "prob.set_val('x', 0.0)\n",
    "prob.set_val('y', 0.0)\n",
    "\n",
    "# this file contains design variable inputs in CSV format\n",
    "with open('saved_cases.csv', 'r') as f:\n",
    "    print(f.read())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "2665ad66",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:48:38.394878Z",
     "iopub.status.busy": "2026-10-02T14:48:38.394754Z",
     "iopub.status.idle": "2026-10-02T14:48:38.964109Z",
     "shell.execute_reply": "2026-10-02T14:48:38.962938Z"
    },
    "papermill": {
     "duration": 0.57243,
     "end_time": "2026-10-02T14:48:38.964579+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:48:38.392149+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x:  0.00, y:  0.00, f_xy:  22.00\n",
      "x:  0.50, y:  0.00, f_xy:  19.25\n",
      "x:  1.00, y:  0.00, f_xy:  17.00\n",
      "x:  0.00, y:  0.50, f_xy:  26.25\n",
      "x:  0.50, y:  0.50, f_xy:  23.75\n",
      "x:  1.00, y:  0.50, f_xy:  21.75\n",
      "x:  0.00, y:  1.00, f_xy:  31.00\n",
      "x:  0.50, y:  1.00, f_xy:  28.75\n",
      "x:  1.00, y:  1.00, f_xy:  27.00\n"
     ]
    }
   ],
   "source": [
    "# run problem with DOEDriver using the CSV file\n",
    "prob.driver = om.DOEDriver(om.CSVGenerator('saved_cases.csv'))\n",
    "prob.driver.add_recorder(om.SqliteRecorder(\"cases.sql\"))\n",
    "\n",
    "prob.run_driver()\n",
    "prob.cleanup()\n",
    "\n",
    "cr = om.CaseReader(prob.get_outputs_dir() / \"cases.sql\")\n",
    "cases = cr.list_cases('driver', out_stream=None)\n",
    "\n",
    "values = []\n",
    "for case in cases:\n",
    "    outputs = cr.get_case(case).outputs\n",
    "    values.append((outputs['x'].item(), outputs['y'].item(), outputs['f_xy'].item()))\n",
    "\n",
    "print(\"\\n\".join([\"x: %5.2f, y: %5.2f, f_xy: %6.2f\" % xyf for xyf in values]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "627411be",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:48:38.970120Z",
     "iopub.status.busy": "2026-10-02T14:48:38.969988Z",
     "iopub.status.idle": "2026-10-02T14:48:38.972297Z",
     "shell.execute_reply": "2026-10-02T14:48:38.971722Z"
    },
    "papermill": {
     "duration": 0.005613,
     "end_time": "2026-10-02T14:48:38.972713+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:48:38.967100+00:00",
     "status": "completed"
    },
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "assert(\"\\n\".join([\"x: %5.2f, y: %5.2f, f_xy: %6.2f\" % xyf for xyf in values]) == expected_text)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "58ddbe60",
   "metadata": {
    "papermill": {
     "duration": 0.002175,
     "end_time": "2026-10-02T14:48:38.977471+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:48:38.975296+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "The second method is to provide the data directly as a list of cases, where each case is a collection of name/value pairs for the design variables. You might use this method if you want to generate the cases programmatically via another algorithm or if the data is available in some format other than a CSV file and you can reformat it into this simple list structure. The `DOEGenerator` you would use in this case is the `ListGenerator`, but if you pass a list directly to the `DOEDriver` it will construct the `ListGenerator` for you. In the following example, a set of cases has been pre-generated and saved in JSON (JavaScript Object Notation) format. The data is decoded and provided to the `DOEDriver` as a list:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "740a6f63",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:48:38.982349Z",
     "iopub.status.busy": "2026-10-02T14:48:38.982224Z",
     "iopub.status.idle": "2026-10-02T14:48:38.985066Z",
     "shell.execute_reply": "2026-10-02T14:48:38.984421Z"
    },
    "papermill": {
     "duration": 0.005935,
     "end_time": "2026-10-02T14:48:38.985508+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:48:38.979573+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[[\"x\", [0.0]], [\"y\", [0.0]]],\n",
      " [[\"x\", [0.5]], [\"y\", [0.0]]],\n",
      " [[\"x\", [1.0]], [\"y\", [0.0]]],\n",
      " [[\"x\", [0.0]], [\"y\", [0.5]]],\n",
      " [[\"x\", [0.5]], [\"y\", [0.5]]],\n",
      " [[\"x\", [1.0]], [\"y\", [0.5]]],\n",
      " [[\"x\", [0.0]], [\"y\", [1.0]]],\n",
      " [[\"x\", [0.5]], [\"y\", [1.0]]],\n",
      " [[\"x\", [1.0]], [\"y\", [1.0]]]]\n"
     ]
    }
   ],
   "source": [
    "# load design variable inputs from JSON file and decode into list\n",
    "with open('cases.json', 'r') as f:\n",
    "    json_data = f.read()\n",
    "\n",
    "print(json_data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "a9a5e2b1",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:48:38.990541Z",
     "iopub.status.busy": "2026-10-02T14:48:38.990414Z",
     "iopub.status.idle": "2026-10-02T14:48:39.337679Z",
     "shell.execute_reply": "2026-10-02T14:48:39.336933Z"
    },
    "papermill": {
     "duration": 0.350344,
     "end_time": "2026-10-02T14:48:39.338140+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:48:38.987796+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x:  0.00, y:  0.00, f_xy:  22.00\n",
      "x:  0.50, y:  0.00, f_xy:  19.25\n",
      "x:  1.00, y:  0.00, f_xy:  17.00\n",
      "x:  0.00, y:  0.50, f_xy:  26.25\n",
      "x:  0.50, y:  0.50, f_xy:  23.75\n",
      "x:  1.00, y:  0.50, f_xy:  21.75\n",
      "x:  0.00, y:  1.00, f_xy:  31.00\n",
      "x:  0.50, y:  1.00, f_xy:  28.75\n",
      "x:  1.00, y:  1.00, f_xy:  27.00\n"
     ]
    }
   ],
   "source": [
    "# create DOEDriver using provided list of cases\n",
    "case_list = json.loads(json_data)\n",
    "prob.driver = om.DOEDriver(case_list)\n",
    "\n",
    "prob.driver.add_recorder(om.SqliteRecorder(\"cases.sql\"))\n",
    "\n",
    "prob.run_driver()\n",
    "prob.cleanup()\n",
    "\n",
    "# check the recorded cases\n",
    "cr = om.CaseReader(prob.get_outputs_dir() / \"cases.sql\")\n",
    "cases = cr.list_cases('driver', out_stream=None)\n",
    "\n",
    "values = []\n",
    "for case in cases:\n",
    "    outputs = cr.get_case(case).outputs\n",
    "    values.append((outputs['x'].item(), outputs['y'].item(), outputs['f_xy'].item()))\n",
    "\n",
    "print(\"\\n\".join([\"x: %5.2f, y: %5.2f, f_xy: %6.2f\" % xyf for xyf in values]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "e9d0224b",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:48:39.392942Z",
     "iopub.status.busy": "2026-10-02T14:48:39.392726Z",
     "iopub.status.idle": "2026-10-02T14:48:39.395571Z",
     "shell.execute_reply": "2026-10-02T14:48:39.394773Z"
    },
    "papermill": {
     "duration": 0.055369,
     "end_time": "2026-10-02T14:48:39.396028+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:48:39.340659+00:00",
     "status": "completed"
    },
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "assert(type(prob.driver.options['generator']) is om.ListGenerator)\n",
    "assert(\"\\n\".join([\"x: %5.2f, y: %5.2f, f_xy: %6.2f\" % xyf for xyf in values]) == expected_text)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "854822d1",
   "metadata": {
    "papermill": {
     "duration": 0.002209,
     "end_time": "2026-10-02T14:48:39.422159+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:48:39.419950+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "```{Note}\n",
    "When using pre-generated cases via `CSVGenerator` or `ListGenerator`, there is no enforcement of the declared bounds on a design variable as with the algorithmic generators.\n",
    "```"
   ]
  }
 ],
 "metadata": {
  "celltoolbar": "Tags",
  "kernelspec": {
   "display_name": "dev",
   "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"
  },
  "mpi": true,
  "orphan": true,
  "papermill": {
   "default_parameters": {},
   "duration": 15.453453,
   "end_time": "2026-10-02T14:48:40.040480+00:00",
   "environment_variables": {},
   "exception": null,
   "input_path": "/home/runner/work/OpenMDAO/OpenMDAO/openmdao/docs/openmdao_book/features/building_blocks/drivers/doe_driver.ipynb",
   "output_path": "/home/runner/work/OpenMDAO/OpenMDAO/openmdao/docs/_executed_book/features/building_blocks/drivers/doe_driver.ipynb",
   "parameters": {},
   "start_time": "2026-10-02T14:48:24.587027+00:00",
   "version": "2.7.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}