{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "active-ipynb",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "try:\n",
    "    from openmdao.utils.notebook_utils import notebook_mode\n",
    "except ImportError:\n",
    "    !python -m pip install openmdao[notebooks]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Upgrading from OpenMDAO 2.10 to OpenMDAO 3\n",
    "\n",
    "In the OpenMDAO 3.0 release, a few changes were made to the API.  In addition, we removed all\n",
    "deprecation warnings and fully deprecated the old behavior for all API changes that were made\n",
    "over the lifespan of OpenMDAO 2.x.  The changes are all summarized here.\n",
    "\n",
    "```{Note}\n",
    "A significant number of the single line examples are a change in class camelcase or removing an underscore\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Building Component Models\n",
    "### Declare a Component with distributed variables\n",
    "\n",
    "````{tabbed} OpenMDAO 2.x\n",
    "```python\n",
    "class DistribComp(ExplicitComponent):\n",
    "\n",
    "    def __init__(self, size):\n",
    "        super().__init__()\n",
    "        self.distributed = True\n",
    "\n",
    "```\n",
    "````\n",
    "\n",
    "`````{tabbed} OpenMDAO 3.0\n",
    "````python\n",
    "import openmdao.api as om\n",
    "\n",
    "\n",
    "class DistribComp(om.ExplicitComponent):\n",
    "    \"\"\"Simple Distributed Component.\"\"\"\n",
    "\n",
    "    def initialize(self):\n",
    "        self.options['distributed'] = True\n",
    "````\n",
    "`````"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "tags": [
     "remove_input"
    ]
   },
   "source": [
    "Below each tabbed example in this notebook is the runnable code from above. However, since some things have been fully deprecated, the code from OpenMDAO 2.x is no longer operational. If that is the case, we have commented out those code cell examples."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "import openmdao.api as om\n",
    "\n",
    "\n",
    "class DistribComp(om.ExplicitComponent):\n",
    "\n",
    "    def __init__(self, size):\n",
    "        super().__init__()\n",
    "        self.distributed = True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "import openmdao.api as om\n",
    "\n",
    "\n",
    "class DistribComp(om.ExplicitComponent):\n",
    "    \"\"\"Simple Distributed Component.\"\"\"\n",
    "\n",
    "    def initialize(self):\n",
    "        self.options['distributed'] = True"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Declare a variable that is explicitly unitless\n",
    "\n",
    "````{tabbed} OpenMDAO 2.x\n",
    "```python\n",
    "prob.model.add_subsystem('tgt', om.ExecComp('y = 3 * x', x={'units': 'unitless'}))\n",
    "```\n",
    "````\n",
    "\n",
    "`````{tabbed} OpenMDAO 3.0\n",
    "````python\n",
    "prob.model.add_subsystem('tgt', om.ExecComp('y = 3 * x', x={'units': None}))\n",
    "````\n",
    "`````"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "prob = om.Problem()\n",
    "prob.model.add_subsystem('tgt', om.ExecComp('y = 3 * x', x={'units': 'unitless'}))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "prob = om.Problem()\n",
    "prob.model.add_subsystem('tgt', om.ExecComp('y = 3 * x', x={'units': None}))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Add a subsystem to a Group\n",
    "\n",
    "````{tabbed} OpenMDAO 2.x\n",
    "```python\n",
    "indeps = prob.model.add('indeps', om.IndepVarComp())\n",
    "```\n",
    "````\n",
    "\n",
    "`````{tabbed} OpenMDAO 3.0\n",
    "````python\n",
    "prob.model.add_subsystem('parab', Paraboloid(), promotes_inputs=['x', 'y'])\n",
    "````\n",
    "`````"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "# This will result in an AttributeError\n",
    "# prob = om.Problem()\n",
    "# indeps = prob.model.add('indeps', om.IndepVarComp())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "from openmdao.test_suite.components.paraboloid import Paraboloid\n",
    "\n",
    "prob = om.Problem()\n",
    "prob.model.add_subsystem('parab', Paraboloid(), promotes_inputs=['x', 'y'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Add a linear or nonlinear solver to a Group\n",
    "\n",
    "````{tabbed} OpenMDAO 2.x\n",
    "```python\n",
    "self.nl_solver = om.NewtonSolver()\n",
    "self.ln_solver = om.DirectSolver()\n",
    "```\n",
    "````\n",
    "\n",
    "`````{tabbed} OpenMDAO 3.0\n",
    "````python\n",
    "self.nonlinear_solver = om.NewtonSolver()\n",
    "self.linear_solver = om.DirectSolver()\n",
    "````\n",
    "`````"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "nl_solver = om.NewtonSolver()\n",
    "ln_solver = om.DirectSolver()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "nonlinear_solver = om.NewtonSolver()\n",
    "linear_solver = om.DirectSolver()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Declare an option with an explicit type\n",
    "\n",
    "````{tabbed} OpenMDAO 2.x\n",
    "```python\n",
    "def initialize(self):\n",
    "    \"\"\"\n",
    "    Declare options.\n",
    "    \"\"\"\n",
    "    self.options.declare('vec_size', type_=int, default=1,\n",
    "                         desc='The number of points at which the vector magnitude is computed')\n",
    "```\n",
    "````\n",
    "\n",
    "`````{tabbed} OpenMDAO 3.0\n",
    "````python\n",
    "def initialize(self):\n",
    "    \"\"\"\n",
    "    Declare options.\n",
    "    \"\"\"\n",
    "    self.options.declare('vec_size', types=int, default=1,\n",
    "                         desc='The number of points at which the vector magnitude is computed')\n",
    "````\n",
    "`````"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "def initialize(self):\n",
    "    \"\"\"\n",
    "    Declare options.\n",
    "    \"\"\"\n",
    "    self.options.declare('vec_size', type_=int, default=1,\n",
    "                         desc='The number of points at which the vector magnitude is computed')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "def initialize(self):\n",
    "    \"\"\"\n",
    "    Declare options.\n",
    "    \"\"\"\n",
    "    self.options.declare('vec_size', types=int, default=1,\n",
    "                         desc='The number of points at which the vector magnitude is computed')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Component Library\n",
    "### Create an interpolating component using Akima spline with uniform grid\n",
    "\n",
    "````{tabbed} OpenMDAO 2.x\n",
    "```python\n",
    "import openmdao.api as om\n",
    "\n",
    "ycp = np.array([5.0, 12.0, 14.0, 16.0, 21.0, 29.0])\n",
    "ncp = len(ycp)\n",
    "n = 11\n",
    "\n",
    "prob = om.Problem()\n",
    "\n",
    "comp = om.AkimaSplineComp(num_control_points=ncp, num_points=n,\n",
    "                          name='chord')\n",
    "\n",
    "prob.model.add_subsystem('comp1', comp)\n",
    "\n",
    "prob.setup()\n",
    "prob['akima.chord:y_cp'] = ycp.reshape((1, ncp))\n",
    "prob.run_model()\n",
    "```\n",
    "````\n",
    "\n",
    "`````{tabbed} OpenMDAO 3.0\n",
    "````python\n",
    "ycp = np.array([5.0, 12.0, 14.0, 16.0, 21.0, 29.0])\n",
    "ncp = len(ycp)\n",
    "n = 11\n",
    "\n",
    "prob = om.Problem()\n",
    "\n",
    "akima_option = {'delta_x': 0.1}\n",
    "comp = om.SplineComp(method='akima', num_cp=ncp, x_interp_val=np.linspace(0.0, 1.0, n),\n",
    "                     interp_options=akima_option)\n",
    "\n",
    "prob.model.add_subsystem('comp1', comp)\n",
    "\n",
    "comp.add_spline(y_cp_name='chord_cp', y_interp_name='chord', y_cp_val=ycp)\n",
    "\n",
    "prob.setup()\n",
    "prob.run_model()\n",
    "````\n",
    "`````"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "# import numpy as np\n",
    "# AkimaSplineComp is no longer a valid class\n",
    "\n",
    "\n",
    "# ycp = np.array([5.0, 12.0, 14.0, 16.0, 21.0, 29.0])\n",
    "# ncp = len(ycp)\n",
    "# n = 11\n",
    "\n",
    "# prob = om.Problem()\n",
    "\n",
    "# comp = om.AkimaSplineComp(num_control_points=ncp, num_points=n,\n",
    "#                           name='chord')\n",
    "\n",
    "# prob.model.add_subsystem('comp1', comp)\n",
    "\n",
    "# prob.setup()\n",
    "# prob['akima.chord:y_cp'] = ycp.reshape((1, ncp))\n",
    "# prob.run_model()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "\n",
    "ycp = np.array([5.0, 12.0, 14.0, 16.0, 21.0, 29.0])\n",
    "ncp = len(ycp)\n",
    "n = 11\n",
    "\n",
    "prob = om.Problem()\n",
    "\n",
    "akima_option = {'delta_x': 0.1}\n",
    "comp = om.SplineComp(method='akima', num_cp=ncp, x_interp_val=np.linspace(0.0, 1.0, n),\n",
    "                     interp_options=akima_option)\n",
    "\n",
    "prob.model.add_subsystem('comp1', comp)\n",
    "\n",
    "comp.add_spline(y_cp_name='chord_cp', y_interp_name='chord', y_cp_val=ycp)\n",
    "\n",
    "prob.setup()\n",
    "prob.run_model()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Create an interpolating component using Akima spline with custom grid\n",
    "\n",
    "````{tabbed} OpenMDAO 2.x\n",
    "```python\n",
    "xcp = np.array([1.0, 2.0, 4.0, 6.0, 10.0, 12.0])\n",
    "ycp = np.array([5.0, 12.0, 14.0, 16.0, 21.0, 29.0])\n",
    "ncp = len(xcp)\n",
    "n = 50\n",
    "x = np.linspace(1.0, 12.0, n)\n",
    "\n",
    "prob = om.Problem()\n",
    "\n",
    "comp = om.AkimaSplineComp(num_control_points=ncp, num_points=n,\n",
    "                          name='chord', input_x=True,\n",
    "                          input_xcp=True)\n",
    "\n",
    "prob.model.add_subsystem('akima', comp)\n",
    "\n",
    "prob.setup(force_alloc_complex=True)\n",
    "\n",
    "prob['akima.chord:x_cp'] = xcp\n",
    "prob['akima.chord:y_cp'] = ycp.reshape((1, ncp))\n",
    "prob['akima.chord:x'] = x\n",
    "\n",
    "prob.run_model()\n",
    "```\n",
    "````\n",
    "\n",
    "`````{tabbed} OpenMDAO 3.0\n",
    "````python\n",
    "xcp = np.array([1.0, 2.0, 4.0, 6.0, 10.0, 12.0])\n",
    "ycp = np.array([5.0, 12.0, 14.0, 16.0, 21.0, 29.0])\n",
    "n = 50\n",
    "x = np.linspace(1.0, 12.0, n)\n",
    "\n",
    "prob = om.Problem()\n",
    "\n",
    "akima_option = {'delta_x': 0.1}\n",
    "comp = om.SplineComp(method='akima', x_cp_val=xcp, x_interp_val=x,\n",
    "                     interp_options=akima_option)\n",
    "\n",
    "prob.model.add_subsystem('akima1', comp)\n",
    "\n",
    "comp.add_spline(y_cp_name='ycp', y_interp_name='y_val', y_cp_val=ycp)\n",
    "\n",
    "prob.setup(force_alloc_complex=True)\n",
    "prob.run_model()\n",
    "````\n",
    "`````"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "# AkimaSplineComp is no longer a valid class\n",
    "\n",
    "\n",
    "# xcp = np.array([1.0, 2.0, 4.0, 6.0, 10.0, 12.0])\n",
    "# ycp = np.array([5.0, 12.0, 14.0, 16.0, 21.0, 29.0])\n",
    "# ncp = len(xcp)\n",
    "# n = 50\n",
    "# x = np.linspace(1.0, 12.0, n)\n",
    "\n",
    "# prob = om.Problem()\n",
    "\n",
    "# comp = om.AkimaSplineComp(num_control_points=ncp, num_points=n,\n",
    "#                           name='chord', input_x=True,\n",
    "#                           input_xcp=True)\n",
    "\n",
    "# prob.model.add_subsystem('akima', comp)\n",
    "\n",
    "# prob.setup(force_alloc_complex=True)\n",
    "\n",
    "# prob['akima.chord:x_cp'] = xcp\n",
    "# prob['akima.chord:y_cp'] = ycp.reshape((1, ncp))\n",
    "# prob['akima.chord:x'] = x\n",
    "\n",
    "# prob.run_model()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "xcp = np.array([1.0, 2.0, 4.0, 6.0, 10.0, 12.0])\n",
    "ycp = np.array([5.0, 12.0, 14.0, 16.0, 21.0, 29.0])\n",
    "n = 50\n",
    "x = np.linspace(1.0, 12.0, n)\n",
    "\n",
    "prob = om.Problem()\n",
    "\n",
    "akima_option = {'delta_x': 0.1}\n",
    "comp = om.SplineComp(method='akima', x_cp_val=xcp, x_interp_val=x,\n",
    "                     interp_options=akima_option)\n",
    "\n",
    "prob.model.add_subsystem('akima1', comp)\n",
    "\n",
    "comp.add_spline(y_cp_name='ycp', y_interp_name='y_val', y_cp_val=ycp)\n",
    "\n",
    "prob.setup(force_alloc_complex=True)\n",
    "prob.run_model()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Create an interpolating component using Bsplines\n",
    "\n",
    "````{tabbed} OpenMDAO 2.x\n",
    "```python\n",
    "prob = om.Problem()\n",
    "model = prob.model\n",
    "\n",
    "n_cp = 5\n",
    "n_point = 10\n",
    "\n",
    "t = np.linspace(0, 0.5*np.pi, n_cp)\n",
    "x = np.empty((2, n_cp))\n",
    "x[0, :] = np.sin(t)\n",
    "x[1, :] = 2.0*np.sin(t)\n",
    "\n",
    "comp = om.BsplinesComp(num_control_points=n_cp,\n",
    "                       num_points=n_point,\n",
    "                       bspline_order=4,\n",
    "                       distribution='sine',\n",
    "                       vec_size=2,\n",
    "                       in_name='h_cp',\n",
    "                       out_name='h')\n",
    "\n",
    "model.add_subsystem('interp', comp)\n",
    "\n",
    "prob.setup()\n",
    "prob.run_model()\n",
    "```\n",
    "````\n",
    "\n",
    "`````{tabbed} OpenMDAO 3.0\n",
    "````python\n",
    "from openmdao.utils.spline_distributions import sine_distribution\n",
    "\n",
    "prob = om.Problem()\n",
    "model = prob.model\n",
    "\n",
    "n_cp = 5\n",
    "n_point = 10\n",
    "\n",
    "t = np.linspace(0, 0.5 * np.pi, n_cp)\n",
    "x = np.empty((2, n_cp))\n",
    "x[0, :] = np.sin(t)\n",
    "x[1, :] = 2.0 * np.sin(t)\n",
    "\n",
    "# In 2.x, the BsplinesComp had a built-in sinusoidal distribution.\n",
    "t_sin = sine_distribution(n_point) * np.pi * 0.5\n",
    "\n",
    "bspline_options = {'order': 4}\n",
    "comp = om.SplineComp(method='bsplines',\n",
    "                     x_interp_val=t_sin,\n",
    "                     num_cp=n_cp,\n",
    "                     vec_size=2,\n",
    "                     interp_options=bspline_options)\n",
    "\n",
    "prob.model.add_subsystem('interp', comp)\n",
    "\n",
    "comp.add_spline(y_cp_name='h_cp', y_interp_name='h', y_cp_val=x, y_units='km')\n",
    "\n",
    "prob.setup()\n",
    "prob.run_model()\n",
    "````\n",
    "`````"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "# BSplineComp is no longer a valid class\n",
    "\n",
    "# prob = om.Problem()\n",
    "# model = prob.model\n",
    "\n",
    "# n_cp = 5\n",
    "# n_point = 10\n",
    "\n",
    "# t = np.linspace(0, 0.5*np.pi, n_cp)\n",
    "# x = np.empty((2, n_cp))\n",
    "# x[0, :] = np.sin(t)\n",
    "# x[1, :] = 2.0*np.sin(t)\n",
    "\n",
    "# comp = om.BsplinesComp(num_control_points=n_cp,\n",
    "#                        num_points=n_point,\n",
    "#                        bspline_order=4,\n",
    "#                        distribution='sine',\n",
    "#                        vec_size=2,\n",
    "#                        in_name='h_cp',\n",
    "#                        out_name='h')\n",
    "\n",
    "# model.add_subsystem('interp', comp)\n",
    "\n",
    "# prob.setup()\n",
    "# prob.run_model()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "from openmdao.utils.spline_distributions import sine_distribution\n",
    "\n",
    "prob = om.Problem()\n",
    "model = prob.model\n",
    "\n",
    "n_cp = 5\n",
    "n_point = 10\n",
    "\n",
    "t = np.linspace(0, 0.5 * np.pi, n_cp)\n",
    "x = np.empty((2, n_cp))\n",
    "x[0, :] = np.sin(t)\n",
    "x[1, :] = 2.0 * np.sin(t)\n",
    "\n",
    "# In 2.x, the BsplinesComp had a built-in sinusoidal distribution.\n",
    "t_sin = sine_distribution(n_point) * np.pi * 0.5\n",
    "\n",
    "bspline_options = {'order': 4}\n",
    "comp = om.SplineComp(method='bsplines',\n",
    "                     x_interp_val=t_sin,\n",
    "                     num_cp=n_cp,\n",
    "                     vec_size=2,\n",
    "                     interp_options=bspline_options)\n",
    "\n",
    "prob.model.add_subsystem('interp', comp)\n",
    "\n",
    "comp.add_spline(y_cp_name='h_cp', y_interp_name='h', y_cp_val=x, y_units='km')\n",
    "\n",
    "prob.setup()\n",
    "prob.run_model()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Create an ExecComp with diagonal partials\n",
    "\n",
    "````{tabbed} OpenMDAO 2.x\n",
    "```python\n",
    "model.add_subsystem('comp', ExecComp('y=3.0*x + 2.5',\n",
    "                                     vectorize=True,\n",
    "                                     x=np.ones(5), y=np.ones(5)))\n",
    "```\n",
    "````\n",
    "\n",
    "`````{tabbed} OpenMDAO 3.0\n",
    "````python\n",
    "model.add_subsystem('comp', om.ExecComp('y=3.0*x + 2.5',\n",
    "                                        has_diag_partials=True,\n",
    "                                        x=np.ones(5), y=np.ones(5)))\n",
    "````\n",
    "`````"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "p = om.Problem()\n",
    "model = p.model\n",
    "\n",
    "model.add_subsystem('comp', om.ExecComp('y=3.0*x + 2.5',\n",
    "                                     vectorize=True,\n",
    "                                     x=np.ones(5), y=np.ones(5)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "p = om.Problem()\n",
    "model = p.model\n",
    "\n",
    "model.add_subsystem('comp', om.ExecComp('y=3.0*x + 2.5',\n",
    "                                        has_diag_partials=True,\n",
    "                                        x=np.ones(5), y=np.ones(5)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Create an IndepVarComp with multiple outputs\n",
    "\n",
    "````{tabbed} OpenMDAO 2.x\n",
    "```python\n",
    "comp = om.IndepVarComp((\n",
    "    ('indep_var_1', 1.0, {'lower': 0, 'upper': 10}),\n",
    "    ('indep_var_2', 2.0, {'lower': 1., 'upper': 20}),\n",
    "))\n",
    "```\n",
    "````\n",
    "\n",
    "`````{tabbed} OpenMDAO 3.0\n",
    "````python\n",
    "comp = om.IndepVarComp()\n",
    "comp.add_output('indep_var_1', val=1.0)\n",
    "comp.add_output('indep_var_2', val=2.0)\n",
    "````\n",
    "`````"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "# comp = om.IndepVarComp((\n",
    "#     ('indep_var_1', 1.0, {'lower': 0, 'upper': 10}),\n",
    "#     ('indep_var_2', 2.0, {'lower': 1., 'upper': 20}),\n",
    "# ))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "comp = om.IndepVarComp()\n",
    "comp.add_output('indep_var_1', val=1.0)\n",
    "comp.add_output('indep_var_2', val=2.0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Create an ExternalCodeComp\n",
    "\n",
    "````{tabbed} OpenMDAO 2.x\n",
    "```python\n",
    "class ParaboloidExternalCodeCompDerivs(om.ExternalCode):\n",
    "```\n",
    "````\n",
    "\n",
    "`````{tabbed} OpenMDAO 3.0\n",
    "````python\n",
    "class ParaboloidExternalCodeCompDerivs(om.ExternalCodeComp):\n",
    "````\n",
    "`````"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "# class ParaboloidExternalCodeCompDerivs(om.ExternalCode):\n",
    "#     pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "class ParaboloidExternalCodeCompDerivs(om.ExternalCodeComp):\n",
    "    pass"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Create a KSComponent\n",
    "\n",
    "````{tabbed} OpenMDAO 2.x\n",
    "```python\n",
    "model.add_subsystem('ks', om.KSComponent(width=2))\n",
    "```\n",
    "````\n",
    "\n",
    "`````{tabbed} OpenMDAO 3.0\n",
    "````python\n",
    "model.add_subsystem('ks', om.KSComp(width=2))\n",
    "````\n",
    "`````"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "# model = om.Problem().model\n",
    "# model.add_subsystem('ks', om.KSComponent(width=2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "model = om.Problem().model\n",
    "model.add_subsystem('ks', om.KSComp(width=2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Create a MetaModel\n",
    "\n",
    "````{tabbed} OpenMDAO 2.x\n",
    "```python\n",
    "sin_mm = om.MetaModel()\n",
    "```\n",
    "````\n",
    "\n",
    "`````{tabbed} OpenMDAO 3.0\n",
    "````python\n",
    "sin_mm = om.MetaModelUnStructuredComp()\n",
    "````\n",
    "`````"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "# sin_mm = om.MetaModel()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "sin_mm = om.MetaModelUnStructuredComp()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Create a MetaModelUnstructured\n",
    "\n",
    "````{tabbed} OpenMDAO 2.x\n",
    "```python\n",
    "sin_mm = om.MetaModelUnstructured()\n",
    "```\n",
    "````\n",
    "\n",
    "`````{tabbed} OpenMDAO 3.0\n",
    "````python\n",
    "sin_mm = om.MetaModelUnStructuredComp()\n",
    "````\n",
    "`````"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "# sin_mm = om.MetaModelUnstructured()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "sin_mm = om.MetaModelUnStructuredComp()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Create a MetaModelStructured\n",
    "\n",
    "````{tabbed} OpenMDAO 2.x\n",
    "```python\n",
    "interp = om.MetaModelStructured(method='scipy_cubic', vec_size=2)\n",
    "```\n",
    "````\n",
    "\n",
    "`````{tabbed} OpenMDAO 3.0\n",
    "````python\n",
    "interp = om.MetaModelStructuredComp(method='scipy_cubic', vec_size=2)\n",
    "````\n",
    "`````"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "# interp = om.MetaModelStructured(method='scipy_cubic', vec_size=2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "interp = om.MetaModelStructuredComp(method='scipy_cubic', vec_size=2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Create a MultiFiMetaModel\n",
    "\n",
    "````{tabbed} OpenMDAO 2.x\n",
    "```python\n",
    "mm = om.MultiFiMetaModel(nfi=2)\n",
    "```\n",
    "````\n",
    "\n",
    "`````{tabbed} OpenMDAO 3.0\n",
    "````python\n",
    "mm = om.MultiFiMetaModelUnStructuredComp(nfi=2)\n",
    "````\n",
    "`````"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "# mm = om.MultiFiMetaModel(nfi=2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "mm = om.MultiFiMetaModelUnStructuredComp(nfi=2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Create a MultiFiMetaModelUnStructured\n",
    "\n",
    "````{tabbed} OpenMDAO 2.x\n",
    "```python\n",
    "mm = om.MultiFiMetaModelUnStructured(nfi=2)\n",
    "```\n",
    "````\n",
    "\n",
    "`````{tabbed} OpenMDAO 3.0\n",
    "````python\n",
    "mm = om.MultiFiMetaModelUnStructuredComp(nfi=2)\n",
    "````\n",
    "`````"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "# mm = om.MultiFiMetaModelUnStructured(nfi=2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "mm = om.MultiFiMetaModelUnStructuredComp(nfi=2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Add a FloatKrigingSurrogate to a MetaModelStructuredComp\n",
    "\n",
    "````{tabbed} OpenMDAO 2.x\n",
    "```python\n",
    "sin_mm.add_output('f_x', 0., surrogate=om.FloatKrigingSurrogate())\n",
    "```\n",
    "````\n",
    "\n",
    "`````{tabbed} OpenMDAO 3.0\n",
    "````python\n",
    "sin_mm.add_output('f_x', 0., surrogate=om.KrigingSurrogate())\n",
    "````\n",
    "`````"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "# sin_mm.add_output('f_x', 0., surrogate=om.FloatKrigingSurrogate())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "sin_mm.add_output('f_x', 0., surrogate=om.KrigingSurrogate())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Specify a default surrogate model for MetaModelStructuredComp\n",
    "\n",
    "````{tabbed} OpenMDAO 2.x\n",
    "```python\n",
    "trig = om.MetaModelUnStructuredComp(vec_size=size)\n",
    "trig.default_surrogate = om.KrigingSurrogate()\n",
    "```\n",
    "````\n",
    "\n",
    "`````{tabbed} OpenMDAO 3.0\n",
    "````python\n",
    "trig = om.MetaModelUnStructuredComp(vec_size=size, default_surrogate=om.KrigingSurrogate())\n",
    "````\n",
    "`````"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "trig = om.MetaModelUnStructuredComp(vec_size=2)\n",
    "trig.default_surrogate = om.KrigingSurrogate()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "trig = om.MetaModelUnStructuredComp(vec_size=2, default_surrogate=om.KrigingSurrogate())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Solvers\n",
    "### Declare a NewtonSolver with solve_subsystems set to False\n",
    "\n",
    "````{tabbed} OpenMDAO 2.x\n",
    "```python\n",
    "newton = model.nonlinear_solver = om.NewtonSolver()\n",
    "```\n",
    "````\n",
    "\n",
    "`````{tabbed} OpenMDAO 3.0\n",
    "````python\n",
    "newton = model.nonlinear_solver = om.NewtonSolver(solve_subsystems=False)\n",
    "````\n",
    "`````"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "newton = model.nonlinear_solver = om.NewtonSolver()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "newton = model.nonlinear_solver = om.NewtonSolver(solve_subsystems=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Control how a solver handles an error raised in a subsolver\n",
    "\n",
    "````{tabbed} OpenMDAO 2.x\n",
    "```python\n",
    "newton = model.nonlinear_solver = NewtonSolver()\n",
    "newton.options['maxiter'] = 1\n",
    "newton.options['err_on_maxiter'] = True\n",
    "```\n",
    "````\n",
    "\n",
    "`````{tabbed} OpenMDAO 3.0\n",
    "````python\n",
    "newton = model.nonlinear_solver = om.NewtonSolver(solve_subsystems=False)\n",
    "newton.options['maxiter'] = 1\n",
    "newton.options['err_on_non_converge'] = True\n",
    "````\n",
    "`````"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "# newton = model.nonlinear_solver = om.NewtonSolver()\n",
    "# newton.options['maxiter'] = 1\n",
    "# newton.options['err_on_maxiter'] = True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "newton = model.nonlinear_solver = om.NewtonSolver(solve_subsystems=False)\n",
    "newton.options['maxiter'] = 1\n",
    "newton.options['err_on_non_converge'] = True"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Declare a BroydenSolver with the BoundsEnforceLS line search\n",
    "\n",
    "````{tabbed} OpenMDAO 2.x\n",
    "```python\n",
    "model.circuit.nonlinear_solver = om.BroydenSolver()\n",
    "model.circuit.nonlinear_solver.linesearch = om.BoundsEnforceLS()\n",
    "```\n",
    "````\n",
    "\n",
    "`````{tabbed} OpenMDAO 3.0\n",
    "````python\n",
    "model.nonlinear_solver = om.BroydenSolver()\n",
    "````\n",
    "`````"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "model = om.Problem().model\n",
    "model.nonlinear_solver = om.BroydenSolver()\n",
    "model.nonlinear_solver.linesearch = om.BoundsEnforceLS()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "model = om.Problem().model\n",
    "model.nonlinear_solver = om.BroydenSolver()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Declare a NewtonSolver with the BoundsEnforceLS line search\n",
    "\n",
    "````{tabbed} OpenMDAO 2.x\n",
    "```python\n",
    "newton = model.nonlinear_solver = om.NewtonSolver(solve_subsystems=False)\n",
    "newton.linesearch = om.BoundsEnforceLS()\n",
    "```\n",
    "````\n",
    "\n",
    "`````{tabbed} OpenMDAO 3.0\n",
    "````python\n",
    "model.nonlinear_solver = om.NewtonSolver(solve_subsystems=False)\n",
    "````\n",
    "`````"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "model = om.Problem().model\n",
    "newton = model.nonlinear_solver = om.NewtonSolver(solve_subsystems=False)\n",
    "newton.linesearch = om.BoundsEnforceLS()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "model = om.Problem().model\n",
    "model.nonlinear_solver = om.NewtonSolver(solve_subsystems=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Add a preconditioner to PETScKrylov\n",
    "\n",
    "````{tabbed} OpenMDAO 2.x\n",
    "```python\n",
    "model.linear_solver = om.PETScKrylov()\n",
    "model.linear_solver.preconditioner = om.LinearBlockGS()\n",
    "```\n",
    "````\n",
    "\n",
    "`````{tabbed} OpenMDAO 3.0\n",
    "````python\n",
    "model.linear_solver = om.PETScKrylov()\n",
    "model.linear_solver.precon = om.LinearBlockGS()\n",
    "````\n",
    "`````"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "model = om.Problem().model\n",
    "\n",
    "# This try/except block is for our CI testing\n",
    "try:\n",
    "    model.linear_solver = om.PETScKrylov()\n",
    "    model.linear_solver.preconditioner = om.LinearBlockGS()\n",
    "except RuntimeError:\n",
    "    pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "model = om.Problem().model\n",
    "\n",
    "try:\n",
    "    model.linear_solver = om.PETScKrylov()\n",
    "    model.linear_solver.precon = om.LinearBlockGS()\n",
    "except RuntimeError:\n",
    "    pass"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Add a preconditioner to ScipyKrylov\n",
    "\n",
    "````{tabbed} OpenMDAO 2.x\n",
    "```python\n",
    "model.linear_solver.preconditioner = om.LinearBlockGS()\n",
    "```\n",
    "````\n",
    "\n",
    "`````{tabbed} OpenMDAO 3.0\n",
    "````python\n",
    "model.linear_solver.precon = om.LinearBlockGS()\n",
    "````\n",
    "`````"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "model = om.Problem().model\n",
    "\n",
    "model.linear_solver.preconditioner = om.LinearBlockGS()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "model = om.Problem().model\n",
    "\n",
    "model.linear_solver.precon = om.LinearBlockGS()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Add a ArmijoGoldsteinLS to a NewtonSolver\n",
    "\n",
    "````{tabbed} OpenMDAO 2.x\n",
    "```python\n",
    "top.model.nonlinear_solver = om.NewtonSolver(solve_subsystems=False)\n",
    "top.model.nonlinear_solver.options['maxiter'] = 10\n",
    "top.model.linear_solver = om.ScipyKrylov()\n",
    "\n",
    "ls = top.model.nonlinear_solver.line_search = om.ArmijoGoldsteinLS(bound_enforcement='vector')\n",
    "```\n",
    "````\n",
    "\n",
    "`````{tabbed} OpenMDAO 3.0\n",
    "````python\n",
    "top.model.nonlinear_solver = om.NewtonSolver(solve_subsystems=False)\n",
    "top.model.nonlinear_solver.options['maxiter'] = 10\n",
    "top.model.linear_solver = om.ScipyKrylov()\n",
    "\n",
    "ls = top.model.nonlinear_solver.linesearch = om.ArmijoGoldsteinLS(bound_enforcement='vector')\n",
    "````\n",
    "`````"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "top = om.Problem()\n",
    "\n",
    "top.model.nonlinear_solver = om.NewtonSolver(solve_subsystems=False)\n",
    "top.model.nonlinear_solver.options['maxiter'] = 10\n",
    "top.model.linear_solver = om.ScipyKrylov()\n",
    "\n",
    "ls = top.model.nonlinear_solver.line_search = om.ArmijoGoldsteinLS(bound_enforcement='vector')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "top = om.Problem()\n",
    "\n",
    "top.model.nonlinear_solver = om.NewtonSolver(solve_subsystems=False)\n",
    "top.model.nonlinear_solver.options['maxiter'] = 10\n",
    "top.model.linear_solver = om.ScipyKrylov()\n",
    "\n",
    "ls = top.model.nonlinear_solver.linesearch = om.ArmijoGoldsteinLS(bound_enforcement='vector')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Create a NonLinearRunOnce\n",
    "\n",
    "````{tabbed} OpenMDAO 2.x\n",
    "```python\n",
    "model.nonlinear_solver = om.NonLinearRunOnce()\n",
    "```\n",
    "````\n",
    "\n",
    "`````{tabbed} OpenMDAO 3.0\n",
    "````python\n",
    "model.nonlinear_solver = om.NonlinearRunOnce()\n",
    "````\n",
    "`````"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "# model = om.Problem().model\n",
    "# model.nonlinear_solver = om.NonLinearRunOnce()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "model = om.Problem().model\n",
    "model.nonlinear_solver = om.NonlinearRunOnce()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Create a PetscKSP\n",
    "\n",
    "````{tabbed} OpenMDAO 2.x\n",
    "```python\n",
    "model.linear_solver = om.PetscKSP()\n",
    "```\n",
    "````\n",
    "\n",
    "`````{tabbed} OpenMDAO 3.0\n",
    "````python\n",
    "model.linear_solver = om.PETScKrylov()\n",
    "````\n",
    "`````"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "# model = om.Problem().model\n",
    "\n",
    "# model.linear_solver = om.PetscKSP()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "model = om.Problem().model\n",
    "try:\n",
    "    model.linear_solver = om.PETScKrylov()\n",
    "except RuntimeError:\n",
    "    pass"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Create a ScipyIterativeSolver\n",
    "\n",
    "````{tabbed} OpenMDAO 2.x\n",
    "```python\n",
    "model.linear_solver = om.ScipyIterativeSolver()\n",
    "```\n",
    "````\n",
    "\n",
    "`````{tabbed} OpenMDAO 3.0\n",
    "````python\n",
    "model.linear_solver = om.ScipyKrylov()\n",
    "````\n",
    "`````"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "# model = om.Problem().model\n",
    "# model.linear_solver = om.ScipyIterativeSolver()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "model = om.Problem().model\n",
    "model.linear_solver = om.ScipyKrylov()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Drivers\n",
    "### Activate dynamic coloring on a Driver\n",
    "\n",
    "````{tabbed} OpenMDAO 2.x\n",
    "```python\n",
    "p.driver.options['dynamic_simul_derivs'] = True\n",
    "```\n",
    "````\n",
    "\n",
    "`````{tabbed} OpenMDAO 3.0\n",
    "````python\n",
    "p.driver.declare_coloring()\n",
    "````\n",
    "`````"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "# p = om.Problem()\n",
    "# p.driver.options['dynamic_simul_derivs'] = True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "p = om.Problem()\n",
    "p.driver.declare_coloring()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Add a ScipyOptimizer to a Problem\n",
    "\n",
    "````{tabbed} OpenMDAO 2.x\n",
    "```python\n",
    "prob.driver = om.ScipyOptimizer()\n",
    "```\n",
    "````\n",
    "\n",
    "`````{tabbed} OpenMDAO 3.0\n",
    "````python\n",
    "prob.driver = om.ScipyOptimizeDriver()\n",
    "````\n",
    "`````"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "# prob = om.Problem()\n",
    "# prob.driver = om.ScipyOptimizer()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "prob = om.Problem()\n",
    "prob.driver = om.ScipyOptimizeDriver()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Working with Derivatives\n",
    "### Use a pre-computed coloring on a model\n",
    "\n",
    "````{tabbed} OpenMDAO 2.x\n",
    "```python\n",
    "p.driver.set_simul_deriv_color()\n",
    "```\n",
    "````\n",
    "\n",
    "`````{tabbed} OpenMDAO 3.0\n",
    "````python\n",
    "p.driver.use_fixed_coloring()\n",
    "````\n",
    "`````"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "# p = om.Problem()\n",
    "# p.driver = om.ScipyOptimizeDriver()\n",
    "# p.driver.set_simul_deriv_color()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "p = om.Problem()\n",
    "p.driver = om.ScipyOptimizeDriver()\n",
    "p.driver.use_fixed_coloring()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Case Reading\n",
    "### Query the iteration coordinate for a case\n",
    "\n",
    "````{tabbed} OpenMDAO 2.x\n",
    "```python\n",
    "cr = om.CaseReader(self.filename)\n",
    "\n",
    "for i, c in enumerate(cr.list_cases()):\n",
    "    case = cr.get_case(c)\n",
    "\n",
    "    coord = case.iteration_coordinate\n",
    "```\n",
    "````\n",
    "\n",
    "`````{tabbed} OpenMDAO 3.0\n",
    "````python\n",
    "cr = om.CaseReader(filename)\n",
    "\n",
    "for i, c in enumerate(cr.list_cases(out_stream=None)):\n",
    "    case = cr.get_case(c)\n",
    "\n",
    "    coord = case.name\n",
    "````\n",
    "`````"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "# This is to create a CaseRecorder\n",
    "from openmdao.test_suite.components.implicit_newton_linesearch import ImplCompTwoStates\n",
    "\n",
    "filename = \"sqlite_test\"\n",
    "recorder = om.SqliteRecorder(filename, record_viewer_data=False)\n",
    "\n",
    "prob = om.Problem()\n",
    "\n",
    "model = prob.model\n",
    "\n",
    "model.add_subsystem('px', om.IndepVarComp('x', 1.0))\n",
    "model.add_subsystem('comp', ImplCompTwoStates())\n",
    "model.connect('px.x', 'comp.x')\n",
    "\n",
    "model.nonlinear_solver = om.NewtonSolver(solve_subsystems=False)\n",
    "model.nonlinear_solver.options['maxiter'] = 3\n",
    "model.nonlinear_solver.options['iprint'] = 2\n",
    "model.linear_solver = om.ScipyKrylov()\n",
    "\n",
    "ls = model.nonlinear_solver.linesearch = om.ArmijoGoldsteinLS(bound_enforcement='vector')\n",
    "ls.options['maxiter'] = 3\n",
    "ls.options['alpha'] = 1.0\n",
    "\n",
    "# add recorder to nonlinear solver, linesearch solver and model\n",
    "model.nonlinear_solver.add_recorder(recorder)\n",
    "model.nonlinear_solver.linesearch.add_recorder(recorder)\n",
    "model.comp.add_recorder(recorder)\n",
    "model.add_recorder(recorder)\n",
    "\n",
    "prob.setup()\n",
    "prob.set_solver_print(0)\n",
    "\n",
    "prob['px.x'] = 2.0\n",
    "prob['comp.y'] = 0.0\n",
    "prob['comp.z'] = 1.6\n",
    "prob.run_model()\n",
    "prob.cleanup()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "# cr = om.CaseReader(filename)\n",
    "\n",
    "# for i, c in enumerate(cr.list_cases()):\n",
    "#     case = cr.get_case(c)\n",
    "\n",
    "#     coord = case.iteration_coordinate"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "cr = om.CaseReader(filename)\n",
    "\n",
    "for i, c in enumerate(cr.list_cases(out_stream=None)):\n",
    "    case = cr.get_case(c)\n",
    "\n",
    "    coord = case.name"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Running a Model\n",
    "### Run a Driver\n",
    "\n",
    "````{tabbed} OpenMDAO 2.x\n",
    "```python\n",
    "prob.run()\n",
    "```\n",
    "````\n",
    "\n",
    "`````{tabbed} OpenMDAO 3.0\n",
    "````python\n",
    "prob.run_driver()\n",
    "````\n",
    "`````"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "# prob = om.Problem()\n",
    "# prob.run()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "prob = om.Problem()\n",
    "prob.setup()\n",
    "prob.run_driver();"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Run a Model without Running the Driver\n",
    "\n",
    "````{tabbed} OpenMDAO 2.x\n",
    "```python\n",
    "prob.run_once()\n",
    "```\n",
    "````\n",
    "\n",
    "`````{tabbed} OpenMDAO 3.0\n",
    "````python\n",
    "prob.run_model()\n",
    "````\n",
    "`````"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "# prob = om.Problem()\n",
    "# prob.run_once()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "prob = om.Problem()\n",
    "prob.setup()\n",
    "prob.run_model()"
   ]
  }
 ],
 "metadata": {
  "celltoolbar": "Tags",
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
