{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "0",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:41:50.617015Z",
     "iopub.status.busy": "2026-10-02T14:41:50.616777Z",
     "iopub.status.idle": "2026-10-02T14:41:50.621295Z",
     "shell.execute_reply": "2026-10-02T14:41:50.620423Z"
    },
    "hide_input": true,
    "papermill": {
     "duration": 0.007989,
     "end_time": "2026-10-02T14:41:50.621869+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:41:50.613880+00:00",
     "status": "completed"
    },
    "tags": [
     "remove-input",
     "remove-output",
     "active-ipynb"
    ]
   },
   "outputs": [],
   "source": [
    "try:\n",
    "    from openmdao.utils.notebook_utils import notebook_mode  # noqa: F401\n",
    "except ImportError:\n",
    "    !python -m pip install openmdao[notebooks]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1",
   "metadata": {
    "papermill": {
     "duration": 0.001003,
     "end_time": "2026-10-02T14:41:50.624212+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:41:50.623209+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "# modOptDriver\n",
    "\n",
    "modOptDriver wraps the optimizers available through the modOpt optimization framework. modOpt provides access to a variety of gradient-based and gradient-free optimization algorithms, including SLSQP, IPOPT, SNOPT, COBYLA, and others. Some of these are available in the package, some need to be separately installed, and some are commercial products that must be obtained from their respective authors (e.g. SNOPT). The modOptDriver supports sparse specification of constraint Jacobians, but not all optimizers can utilize the sparsity.\n",
    "\n",
    "In this example, we use the SLSQP optimizer to minimize the objective of the Paraboloid problem."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "2",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:41:50.626951Z",
     "iopub.status.busy": "2026-10-02T14:41:50.626823Z",
     "iopub.status.idle": "2026-10-02T14:41:52.607482Z",
     "shell.execute_reply": "2026-10-02T14:41:52.606238Z"
    },
    "papermill": {
     "duration": 1.982822,
     "end_time": "2026-10-02T14:41:52.608076+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:41:50.625254+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_src020"
      }
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "from openmdao.utils.notebook_utils import get_code\n",
    "from myst_nb import glue\n",
    "glue(\"code_src020\", get_code(\"openmdao.test_suite.components.paraboloid.Paraboloid\"), display=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3",
   "metadata": {
    "papermill": {
     "duration": 0.001425,
     "end_time": "2026-10-02T14:41:52.610936+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:41:52.609511+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    ":::{dropdown} `Paraboloid` class definition \n",
    "\n",
    "{glue:}`code_src020`\n",
    ":::"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "4",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:41:52.614025Z",
     "iopub.status.busy": "2026-10-02T14:41:52.613873Z",
     "iopub.status.idle": "2026-10-02T14:41:53.896046Z",
     "shell.execute_reply": "2026-10-02T14:41:53.895357Z"
    },
    "papermill": {
     "duration": 1.284652,
     "end_time": "2026-10-02T14:41:53.896813+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:41:52.612161+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1790952113.850839] [runnervm8df0l:6897 :0]        ib_iface.c:1269 UCX  ERROR mana_0: iface 0x55ee7979dfe0 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",
      "[1790952113.851085] [runnervm8df0l:6897 :0]      ucp_worker.c:1412 UCX  ERROR uct_iface_open(ud_verbs/mana_0:1) failed: Input/output error\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Setting objective name as \"f_xy\".\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Optimization terminated successfully    (Exit mode 0)\n",
      "            Current function value: -27.33333333333333\n",
      "            Iterations: 3\n",
      "            Function evaluations: 4\n",
      "            Gradient evaluations: 3\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Optimization Complete\n",
      "-----------------------------------\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[runnervm8df0l:06897] pml_ucx.c:313  Error: Failed to create UCP worker\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "Problem: problem\n",
       "Driver:  modOptDriver\n",
       "  success     : True\n",
       "  iterations  : 6\n",
       "  runtime     : 3.0653E-02 s\n",
       "  model_evals : 6\n",
       "  model_time  : 4.5778E-04 s\n",
       "  deriv_evals : 0\n",
       "  deriv_time  : 0.0000E+00 s\n",
       "  exit_status : SUCCESS"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "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",
    "prob.driver = om.modOptDriver()\n",
    "prob.driver.options['optimizer'] = 'SLSQP'\n",
    "prob.driver.options['maxiter'] = 200\n",
    "prob.driver.options['disp'] = True\n",
    "\n",
    "model.add_design_var('x', lower=-50.0, upper=50.0)\n",
    "model.add_design_var('y', lower=-50.0, upper=50.0)\n",
    "model.add_objective('f_xy')\n",
    "\n",
    "prob.setup()\n",
    "\n",
    "prob.set_val('x', 50.0)\n",
    "prob.set_val('y', 50.0)\n",
    "\n",
    "prob.run_driver()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "18cb7651",
   "metadata": {
    "papermill": {
     "duration": 0.001403,
     "end_time": "2026-10-02T14:41:53.899833+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:41:53.898430+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "The \"optimizer\" option lets you choose which optimizer to use. modOptDriver provides access to a wide range of optimizers through the modOpt framework. The supported optimizers are (case sensitive):\n",
    "\n",
    "**Gradient-Based:**\n",
    "- \"SLSQP\" - Sequential Least Squares Programming (default optimizer)\n",
    "- \"PySLSQP\" - Pure Python implementation of SLSQP with expanded features\n",
    "- \"BFGS\" - Broyden-Fletcher-Goldfarb-Shanno (unconstrained only)\n",
    "- \"LBFGSB\" - Limited-memory BFGS with bounds\n",
    "- \"TrustConstr\" - Trust-region constrained algorithm\n",
    "- \"IPOPT\" - Interior Point Optimizer\n",
    "- \"SNOPT\" - Sparse Nonlinear Optimizer (requires license)\n",
    "- \"OpenSQP\" - Sequential Quadratic Programming built into modOpt\n",
    "\n",
    "**Gradient-Free:**\n",
    "- \"COBYLA\" - Constrained Optimization BY Linear Approximation\n",
    "- \"COBYQA\" - Constrained Optimization BY Quadratic Approximation (improved COBYLA)\n",
    "- \"NelderMead\" - Nelder-Mead simplex algorithm (unconstrained only)\n",
    "\n",
    "```{note}\n",
    "OpenMDAO installs only the base modOpt package. Some optimizers listed above require\n",
    "additional packages that must be installed manually in your environment. Most of the optimizers (SLSQP, BFGS, LBFGSB, TrustConstr, COBYLA, COBYQA, NelderMead)\n",
    "are available through SciPy and are included with the base modOpt installation.\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "5",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:41:53.945072Z",
     "iopub.status.busy": "2026-10-02T14:41:53.944798Z",
     "iopub.status.idle": "2026-10-02T14:41:53.947671Z",
     "shell.execute_reply": "2026-10-02T14:41:53.947159Z"
    },
    "papermill": {
     "duration": 0.006047,
     "end_time": "2026-10-02T14:41:53.948343+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:41:53.942296+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[6.66666667]\n"
     ]
    }
   ],
   "source": [
    "print(prob.get_val('x'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "6",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:41:53.992490Z",
     "iopub.status.busy": "2026-10-02T14:41:53.992288Z",
     "iopub.status.idle": "2026-10-02T14:41:53.995879Z",
     "shell.execute_reply": "2026-10-02T14:41:53.995212Z"
    },
    "papermill": {
     "duration": 0.006495,
     "end_time": "2026-10-02T14:41:53.996294+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:41:53.989799+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[-7.33333333]\n"
     ]
    }
   ],
   "source": [
    "print(prob.get_val('y'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "7",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:41:54.001011Z",
     "iopub.status.busy": "2026-10-02T14:41:54.000824Z",
     "iopub.status.idle": "2026-10-02T14:41:54.005905Z",
     "shell.execute_reply": "2026-10-02T14:41:54.005133Z"
    },
    "hide_input": true,
    "papermill": {
     "duration": 0.008444,
     "end_time": "2026-10-02T14:41:54.006465+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:41:53.998021+00:00",
     "status": "completed"
    },
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "np.float64(4.5454546999778205e-09)"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from openmdao.utils.assert_utils import assert_near_equal\n",
    "assert_near_equal(prob.get_val('x'), 6.66666667, 1e-6)\n",
    "assert_near_equal(prob.get_val('y'), -7.3333333, 1e-6)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8",
   "metadata": {
    "papermill": {
     "duration": 0.001471,
     "end_time": "2026-10-02T14:41:54.009513+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:41:54.008042+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "## modOptDriver Options"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "9",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:41:54.013091Z",
     "iopub.status.busy": "2026-10-02T14:41:54.012953Z",
     "iopub.status.idle": "2026-10-02T14:41:54.016855Z",
     "shell.execute_reply": "2026-10-02T14:41:54.015971Z"
    },
    "papermill": {
     "duration": 0.006487,
     "end_time": "2026-10-02T14:41:54.017434+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:41:54.010947+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;\">disp</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">True</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">N/A</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">[&#x27;int&#x27;, &#x27;bool&#x27;]</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">Controls optimizer output verbosity. Can be bool (True/False) or int for fine control (0=quiet, higher=more verbose). Automatically maps to optimizer-specific settings. If optimizer specific verbosity settings are provided in the &quot;opt_settings&quot; attribute, then this option will be ignored and those settings will be used instead.</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;\">maxiter</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">200</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">N/A</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">N/A</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">Maximum number of iterations.</td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">optimizer</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">SLSQP</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">[&#x27;COBYQA&#x27;, &#x27;LBFGSB&#x27;, &#x27;BFGS&#x27;, &#x27;PySLSQP&#x27;, &#x27;TrustConstr&#x27;, &#x27;OpenSQP&#x27;, &#x27;SLSQP&#x27;, &#x27;ConvexQPSolvers&#x27;, &#x27;NelderMead&#x27;, &#x27;Egor&#x27;, &#x27;IPOPT&#x27;, &#x27;SNOPT&#x27;, &#x27;COBYLA&#x27;, &#x27;CVXOPT&#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;\">Name of optimizer to use</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">output_dir</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">DEFAULT_REPORTS_DIR</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;str&#x27;, &#x27;_ReprClass&#x27;]</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">The directory to store all the output files generated from the optimization.</td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">singular_jac_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;error&#x27;, &#x27;warn&#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;\">Defines behavior of a zero row/col check after first call to compute_totals: error - raise an error. warn - raise a warning. ignore - don&#x27;t perform check.</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">singular_jac_tol</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">1e-16</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">N/A</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">N/A</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">Tolerance for zero row/column check.</td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">turn_off_outputs</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">False</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">[True, False]</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">[&#x27;bool&#x27;]</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">If True, prevents modOpt from generating any output files.</td></tr>\n",
       "    </table>\n",
       "</body>\n",
       "</html>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "om.show_options_table(\"openmdao.drivers.modopt_driver.modOptDriver\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "10",
   "metadata": {
    "papermill": {
     "duration": 0.001542,
     "end_time": "2026-10-02T14:41:54.020684+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:41:54.019142+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "## modOptDriver Constructor\n",
    "\n",
    "The call signature for the *modOptDriver* constructor is:\n",
    "\n",
    "```{eval-rst}\n",
    "    .. automethod:: openmdao.drivers.modopt_driver.modOptDriver.__init__\n",
    "        :noindex:\n",
    "```\n",
    "\n",
    "## Using modOptDriver\n",
    "\n",
    "modOptDriver has a small number of unified options that can be specified as keyword arguments when it is instantiated or by using the “options” dictionary. We have already shown how to set the optimizer option. Next we will see how `maxiter` and `disp` can be used to control the maxinum number of iterations and what the optimizer displays. The \"disp\" option controls optimizer output verbosity. You can set it to True/False or an integer for fine control (0=quiet, higher=more verbose). This setting is automatically mapped to the optimizer's output settings."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "16",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:41:54.025933Z",
     "iopub.status.busy": "2026-10-02T14:41:54.025771Z",
     "iopub.status.idle": "2026-10-02T14:41:54.039226Z",
     "shell.execute_reply": "2026-10-02T14:41:54.038410Z"
    },
    "papermill": {
     "duration": 0.016875,
     "end_time": "2026-10-02T14:41:54.039736+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:41:54.022861+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Setting objective name as \"f_xy\".\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "Problem: problem2\n",
       "Driver:  modOptDriver\n",
       "  success     : True\n",
       "  iterations  : 6\n",
       "  runtime     : 5.8091E-03 s\n",
       "  model_evals : 6\n",
       "  model_time  : 4.5426E-04 s\n",
       "  deriv_evals : 0\n",
       "  deriv_time  : 0.0000E+00 s\n",
       "  exit_status : SUCCESS"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "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",
    "prob.driver = om.modOptDriver()\n",
    "prob.driver.options['maxiter'] = 20\n",
    "prob.driver.options['disp'] = False\n",
    "\n",
    "model.add_design_var('x', lower=-50.0, upper=50.0)\n",
    "model.add_design_var('y', lower=-50.0, upper=50.0)\n",
    "model.add_objective('f_xy')\n",
    "\n",
    "prob.setup()\n",
    "\n",
    "prob.set_val('x', 50.0)\n",
    "prob.set_val('y', 50.0)\n",
    "\n",
    "prob.run_driver()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "17",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:41:54.043834Z",
     "iopub.status.busy": "2026-10-02T14:41:54.043636Z",
     "iopub.status.idle": "2026-10-02T14:41:54.046469Z",
     "shell.execute_reply": "2026-10-02T14:41:54.045871Z"
    },
    "papermill": {
     "duration": 0.006039,
     "end_time": "2026-10-02T14:41:54.047443+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:41:54.041404+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[6.66666667]\n"
     ]
    }
   ],
   "source": [
    "print(prob.get_val('x'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "18",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:41:54.052363Z",
     "iopub.status.busy": "2026-10-02T14:41:54.052188Z",
     "iopub.status.idle": "2026-10-02T14:41:54.055518Z",
     "shell.execute_reply": "2026-10-02T14:41:54.054625Z"
    },
    "papermill": {
     "duration": 0.007207,
     "end_time": "2026-10-02T14:41:54.056349+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:41:54.049142+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[-7.33333333]\n"
     ]
    }
   ],
   "source": [
    "print(prob.get_val('y'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "19",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:41:54.067908Z",
     "iopub.status.busy": "2026-10-02T14:41:54.067741Z",
     "iopub.status.idle": "2026-10-02T14:41:54.070987Z",
     "shell.execute_reply": "2026-10-02T14:41:54.070371Z"
    },
    "hide_input": true,
    "papermill": {
     "duration": 0.012677,
     "end_time": "2026-10-02T14:41:54.071555+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:41:54.058878+00:00",
     "status": "completed"
    },
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "np.float64(4.5454546999778205e-09)"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "assert_near_equal(prob.get_val('x'), 6.66666667, 1e-6)\n",
    "assert_near_equal(prob.get_val('y'), -7.3333333, 1e-6)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "23",
   "metadata": {
    "papermill": {
     "duration": 0.001899,
     "end_time": "2026-10-02T14:41:54.075420+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:41:54.073521+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "## modOptDriver Optimizer-Specific Options\n",
    "\n",
    "Each optimizer in modOpt has its own set of specific options that control its behavior. You can set these optimizer-specific options through the `opt_settings` dictionary. See the [modOpt documentation](https://modopt.readthedocs.io) for detailed information about available settings for each optimizer.\n",
    "\n",
    "For example, here's code setting some specific options for the SLSQP optimizer:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "24",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:41:54.080187Z",
     "iopub.status.busy": "2026-10-02T14:41:54.080034Z",
     "iopub.status.idle": "2026-10-02T14:41:54.093017Z",
     "shell.execute_reply": "2026-10-02T14:41:54.092401Z"
    },
    "papermill": {
     "duration": 0.016281,
     "end_time": "2026-10-02T14:41:54.093674+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:41:54.077393+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Setting objective name as \"f_xy\".\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "Problem: problem3\n",
       "Driver:  modOptDriver\n",
       "  success     : True\n",
       "  iterations  : 6\n",
       "  runtime     : 5.1410E-03 s\n",
       "  model_evals : 6\n",
       "  model_time  : 3.9576E-04 s\n",
       "  deriv_evals : 0\n",
       "  deriv_time  : 0.0000E+00 s\n",
       "  exit_status : SUCCESS"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "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",
    "prob.driver = driver = om.modOptDriver()\n",
    "driver.options['optimizer'] = 'SLSQP'\n",
    "driver.options['maxiter'] = 100\n",
    "driver.options['disp'] = False\n",
    "\n",
    "# Set optimizer-specific options through opt_settings. Here we set the precision for\n",
    "# the final solution with the \"ftol\" setting specific to SLSQP\n",
    "driver.opt_settings['ftol'] = 1e-8\n",
    "\n",
    "model.add_design_var('x', lower=-50.0, upper=50.0)\n",
    "model.add_design_var('y', lower=-50.0, upper=50.0)\n",
    "model.add_objective('f_xy')\n",
    "\n",
    "prob.setup()\n",
    "\n",
    "prob.set_val('x', 50.0)\n",
    "prob.set_val('y', 50.0)\n",
    "\n",
    "prob.run_driver()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "25",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:41:54.107933Z",
     "iopub.status.busy": "2026-10-02T14:41:54.107730Z",
     "iopub.status.idle": "2026-10-02T14:41:54.111834Z",
     "shell.execute_reply": "2026-10-02T14:41:54.111095Z"
    },
    "hide_input": true,
    "papermill": {
     "duration": 0.007295,
     "end_time": "2026-10-02T14:41:54.112320+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:41:54.105025+00:00",
     "status": "completed"
    },
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "np.float64(4.5454546999778205e-09)"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "assert_near_equal(prob.get_val('x'), 6.66666667, 1e-6)\n",
    "assert_near_equal(prob.get_val('y'), -7.3333333, 1e-6)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "om-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"
  },
  "orphan": true,
  "papermill": {
   "default_parameters": {},
   "duration": 4.963157,
   "end_time": "2026-10-02T14:41:54.830182+00:00",
   "environment_variables": {},
   "exception": null,
   "input_path": "/home/runner/work/OpenMDAO/OpenMDAO/openmdao/docs/openmdao_book/features/building_blocks/drivers/modopt_driver.ipynb",
   "output_path": "/home/runner/work/OpenMDAO/OpenMDAO/openmdao/docs/_executed_book/features/building_blocks/drivers/modopt_driver.ipynb",
   "parameters": {},
   "start_time": "2026-10-02T14:41:49.867025+00:00",
   "version": "2.7.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}