{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "jupyter": {
     "outputs_hidden": false
    },
    "pycharm": {
     "name": "#%%\n"
    },
    "tags": [
     "remove-input",
     "remove-output",
     "active-ipynb"
    ]
   },
   "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": [
    "# Adding an Objective\n",
    "\n",
    "To add an objective to an optimization, use the `add_objective` method on System."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```{eval-rst}\n",
    "    .. automethod:: openmdao.core.system.System.add_objective\n",
    "        :noindex:\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Specifying units\n",
    "\n",
    "You can specify units when adding an objective. When this is done, the quanitity is converted from the target output’s units to the desired unit before giving it to the optimizer. If you also specify scaling, that scaling is applied after the unit conversion. Moreover, the upper and lower bound should be specified using these units."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "jupyter": {
     "outputs_hidden": false
    },
    "pycharm": {
     "name": "#%%\n"
    },
    "tags": [
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "import openmdao.api as om\n",
    "\n",
    "prob = om.Problem()\n",
    "model = prob.model\n",
    "\n",
    "model.add_subsystem('comp1', om.ExecComp('y1 = 2.0*x',\n",
    "                                         x={'val': 2.0, 'units': 'degF'},\n",
    "                                         y1={'val': 2.0, 'units': 'degF'}),\n",
    "                    promotes=['x', 'y1'])\n",
    "\n",
    "model.add_subsystem('comp2', om.ExecComp('y2 = 3.0*x',\n",
    "                                         x={'val': 2.0, 'units': 'degF'},\n",
    "                                         y2={'val': 2.0, 'units': 'degF'}),\n",
    "                    promotes=['x', 'y2'])\n",
    "\n",
    "model.set_input_defaults('x', 35.0, units='degF')\n",
    "\n",
    "model.add_design_var('x', units='degC', lower=0.0, upper=100.0)\n",
    "model.add_constraint('y1', units='degC', lower=0.0, upper=100.0)\n",
    "model.add_objective('y2', units='degC')\n",
    "\n",
    "prob.setup()\n",
    "prob.run_driver()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "jupyter": {
     "outputs_hidden": false
    },
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "print('Model variables')\n",
    "print(prob.get_val('x', indices=[0]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "jupyter": {
     "outputs_hidden": false
    },
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "print(prob.get_val('comp2.y2', indices=[0]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "jupyter": {
     "outputs_hidden": false
    },
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "print(prob.get_val('comp1.y1', indices=[0]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "jupyter": {
     "outputs_hidden": false
    },
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "print('Driver variables')\n",
    "dv = prob.driver.get_design_var_values()\n",
    "print(dv['x'][0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "jupyter": {
     "outputs_hidden": false
    },
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "obj = prob.driver.get_objective_values(driver_scaling=True)\n",
    "print(obj['comp2.y2'][0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "jupyter": {
     "outputs_hidden": false
    },
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "con = prob.driver.get_constraint_values(driver_scaling=True)\n",
    "print(con['comp1.y1'][0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "jupyter": {
     "outputs_hidden": false
    },
    "pycharm": {
     "name": "#%%\n"
    },
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "from openmdao.utils.assert_utils import assert_near_equal\n",
    "\n",
    "assert_near_equal(prob.get_val('x', indices=[0]), 35.)\n",
    "assert_near_equal(prob.get_val('comp2.y2', indices=[0]), 105.)\n",
    "assert_near_equal(prob.get_val('comp1.y1', indices=[0]), 70.)\n",
    "assert_near_equal(dv['x'][0], 1.6666666666666983)\n",
    "assert_near_equal(obj['comp2.y2'][0], 40.555555555555586)\n",
    "assert_near_equal(con['comp1.y1'][0], 21.111111111111143)"
   ]
  }
 ],
 "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.8.8"
  },
  "orphan": true
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
