{
 "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": [
    "# Understanding How Variables Work\n",
    "\n",
    "In general, a numerical model can be complex, multidisciplinary, and heterogeneous.\n",
    "It can be decomposed into a series of smaller computations that are chained together.\n",
    "\n",
    "\n",
    "## A Simple Numerical Model\n",
    "\n",
    "Let us consider the following numerical model that takes $x$ as an input:\n",
    "\n",
    "$$\n",
    "  \\begin{array}{l l}\n",
    "    y \\quad \\text{is computed by solving:} &\n",
    "    \\cos(x \\cdot y) - z \\cdot y = 0  \\\\\n",
    "    z \\quad \\text{is computed by evaluating:} &\n",
    "    z = \\sin(y) .\n",
    "  \\end{array}\n",
    "$$\n",
    "\n",
    "OpenMDAO reformulates all numerical models into the form of a nonlinear system which drives a set of residual equations to 0.\n",
    "This is done so that all models 'look the same' to the framework,\n",
    "which helps simplify methods for converging coupled numerical models and for computing their derivatives\n",
    "(i.e., $dz/dx$ and $dy/dx$ in this case).\n",
    "If we say we want to evaluate the numerical model at $x=\\pi$, the reformulation would be:\n",
    "\n",
    "\n",
    "$$\n",
    "  \\begin{array}{l}\n",
    "    R_x(x, y, z) = x - \\pi \\\\\n",
    "    R_y(x, y, z) = \\cos(x \\cdot y) - z \\cdot y \\\\\n",
    "    R_z(x, y, z) = z - \\sin(y) .\n",
    "  \\end{array}\n",
    "$$\n",
    "\n",
    "The variables in this model would be x, y, and z.\n",
    "\n",
    "## The Relationship Between Variables and Components\n",
    "\n",
    "In OpenMDAO, all three of these variables would be defined as the output of one or more `Component` instances.\n",
    "There are two main component types:\n",
    "\n",
    "- [ExplicitComponent](../_srcdocs/packages/core/explicitcomponent.ipynb)\n",
    "- [ImplicitComponent](../_srcdocs/packages/core/implicitcomponent.ipynb)\n",
    "\n",
    "The `ExplicitComponent` allows you to define your equations in the explicit form (e.g. $z = \\sin(y)$) and it computes the implicit transformation for you in order to compute the residuals.\n",
    "The `ImplicitComponent` expects you to compute all the residuals yourself in the `apply_linear` method.\n",
    "Regardless of which type of component you chose, OpenMDAO sees everything in the implicit form, and treats your model as system of nonlinear equations.\n",
    "\n",
    "Multiple components can be aggregated into a hierarchy with the `Group` class.\n",
    "A Group is seen by OpenMDAO as a collection of all the implicit equations from all of its children components.\n",
    "Since both `Component` and `Group` represent systems of nonlinear equations,\n",
    "you call the [add_system](../features/core_features/working_with_groups/add_subsystem.ipynb) method to construct a model hierarchy.\n",
    "\n",
    "```{note}\n",
    "The underlying mathematics that power OpenMDAO are based on the [MAUD](https://mdolab.engin.umich.edu/bibliography/Hwang2018a) architecture, which established the foundation for treating a multidisciplinary model as a single system of nonlinear equations as a means to efficiently computing analytic derivatives across it.\n",
    "```"
   ]
  }
 ],
 "metadata": {
  "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.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
