{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Physical constants"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A couple of short examples of using `aeolus` physical contants submodule, which can serve as a convenient way to store a number of constants used in an atmospheric model."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from aeolus.const import init_const"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## General constants"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "First, generic (planet-independent constants) are available."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "gen = init_const()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here, `gen` is a dataclass-like object containing a few constants. Each of the constants is stored with appropriate units as an `iris.cube.Cube`."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For example, in this example the container has the heat of vaporization of water (at 0 deg C)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "<style>\n",
       "  a.iris {\n",
       "      text-decoration: none !important;\n",
       "  }\n",
       "  table.iris {\n",
       "      white-space: pre;\n",
       "      border: 1px solid;\n",
       "      border-color: #9c9c9c;\n",
       "      font-family: monaco, monospace;\n",
       "  }\n",
       "  th.iris {\n",
       "      background: #303f3f;\n",
       "      color: #e0e0e0;\n",
       "      border-left: 1px solid;\n",
       "      border-color: #9c9c9c;\n",
       "      font-size: 1.05em;\n",
       "      min-width: 50px;\n",
       "      max-width: 125px;\n",
       "  }\n",
       "  tr.iris :first-child {\n",
       "      border-right: 1px solid #9c9c9c !important;\n",
       "  }\n",
       "  td.iris-title {\n",
       "      background: #d5dcdf;\n",
       "      border-top: 1px solid #9c9c9c;\n",
       "      font-weight: bold;\n",
       "  }\n",
       "  .iris-word-cell {\n",
       "      text-align: left !important;\n",
       "      white-space: pre;\n",
       "  }\n",
       "  .iris-subheading-cell {\n",
       "      padding-left: 2em !important;\n",
       "  }\n",
       "  .iris-inclusion-cell {\n",
       "      padding-right: 1em !important;\n",
       "  }\n",
       "  .iris-panel-body {\n",
       "      padding-top: 0px;\n",
       "  }\n",
       "  .iris-panel-title {\n",
       "      padding-left: 3em;\n",
       "  }\n",
       "  .iris-panel-title {\n",
       "      margin-top: 7px;\n",
       "  }\n",
       "</style>\n",
       "<table class=\"iris\" id=\"140072314338464\">\n",
       "    <tr class=\"iris\">\n",
       "<th class=\"iris iris-word-cell\">Water Heat Vaporization (m2 s-2)</th>\n",
       "<th class=\"iris iris-word-cell\">(scalar cube)</th>\n",
       "</tr>\n",
       "    \n",
       "    \n",
       "</table>\n",
       "        "
      ],
      "text/plain": [
       "<iris 'Cube' of water_heat_vaporization / (m2 s-2) (scalar cube)>"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "L = gen.water_heat_vaporization\n",
    "L"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "iris.cube.Cube"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(L)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(array(2501000.), Unit('m2 s-2'))"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "L.data, L.units"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Having constants stored as iris cubes is convenient for unit-aware operations."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Earth constants"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Along with `aeolus`, some basic constants of the Earth atmosphere are also provided. Note that all the \"generic\" constants are also added to this container."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "EarthConstants(earth_day [s], stefan_boltzmann [W m-2 K-4], water_heat_vaporization [m2 s-2], water_molecular_weight [kg mol-1], molar_gas_constant [J K-1 mol-1], boltzmann [m^2 kg s^-2 K^-1], avogadro [mol-1], gravity [m s-2], radius [m], day [s], solar_constant [W m-2], semi_major_axis [au], eccentricity [1], obliquity [degree], dry_air_spec_heat_press [m2 s-2 K-1], dry_air_molecular_weight [kg mol-1], condensible_density [kg m-3], condensible_heat_vaporization [m2 s-2], condensible_molecular_weight [kg mol-1], reference_surface_pressure [Pa])"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "earth_const = init_const(\"earth\")\n",
    "earth_const"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "c_p = earth_const.dry_air_spec_heat_press"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "It is possible to derive the gas constant for dry air using the universal gas constant."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "r_d = gen.molar_gas_constant / earth_const.dry_air_molecular_weight\n",
    "r_d.rename(\"dry_air_gas_constant\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "<style>\n",
       "  a.iris {\n",
       "      text-decoration: none !important;\n",
       "  }\n",
       "  table.iris {\n",
       "      white-space: pre;\n",
       "      border: 1px solid;\n",
       "      border-color: #9c9c9c;\n",
       "      font-family: monaco, monospace;\n",
       "  }\n",
       "  th.iris {\n",
       "      background: #303f3f;\n",
       "      color: #e0e0e0;\n",
       "      border-left: 1px solid;\n",
       "      border-color: #9c9c9c;\n",
       "      font-size: 1.05em;\n",
       "      min-width: 50px;\n",
       "      max-width: 125px;\n",
       "  }\n",
       "  tr.iris :first-child {\n",
       "      border-right: 1px solid #9c9c9c !important;\n",
       "  }\n",
       "  td.iris-title {\n",
       "      background: #d5dcdf;\n",
       "      border-top: 1px solid #9c9c9c;\n",
       "      font-weight: bold;\n",
       "  }\n",
       "  .iris-word-cell {\n",
       "      text-align: left !important;\n",
       "      white-space: pre;\n",
       "  }\n",
       "  .iris-subheading-cell {\n",
       "      padding-left: 2em !important;\n",
       "  }\n",
       "  .iris-inclusion-cell {\n",
       "      padding-right: 1em !important;\n",
       "  }\n",
       "  .iris-panel-body {\n",
       "      padding-top: 0px;\n",
       "  }\n",
       "  .iris-panel-title {\n",
       "      padding-left: 3em;\n",
       "  }\n",
       "  .iris-panel-title {\n",
       "      margin-top: 7px;\n",
       "  }\n",
       "</style>\n",
       "<table class=\"iris\" id=\"140071909694768\">\n",
       "    <tr class=\"iris\">\n",
       "<th class=\"iris iris-word-cell\">Dry Air Gas Constant (m2.s-2.K-1)</th>\n",
       "<th class=\"iris iris-word-cell\">(scalar cube)</th>\n",
       "</tr>\n",
       "    \n",
       "    \n",
       "</table>\n",
       "        "
      ],
      "text/plain": [
       "<iris 'Cube' of dry_air_gas_constant / (m2.s-2.K-1) (scalar cube)>"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "r_d"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array(287.05797807)"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "r_d.data"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Extending constants container"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "All constants shown above are stored in JSON files, so it is possible to create a custom JSON file and read constants from it."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pathlib import Path"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For example, we have an `example.json` file in the `sample_data` sub-directory. The file looks like this:\n",
    "\n",
    "```json\n",
    "[                                                                               \n",
    "    {                                                                           \n",
    "        \"name\": \"my_constant\",                                                  \n",
    "        \"units\": \"m s-1\",                                                       \n",
    "        \"value\": 123.456                                                        \n",
    "    }                                                                           \n",
    "]       \n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Then it can be loaded in the following way."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "ex_const = init_const(name=\"example\", directory=(Path.cwd() / \"sample_data\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "ExampleConstants(earth_day [s], stefan_boltzmann [W m-2 K-4], water_heat_vaporization [m2 s-2], water_molecular_weight [kg mol-1], molar_gas_constant [J K-1 mol-1], boltzmann [m^2 kg s^-2 K^-1], avogadro [mol-1], my_constant [m s-1])"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ex_const"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In this case, the JSON file contains only one constant, `my_constant`, the rest are \"general\" constants."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "<style>\n",
       "  a.iris {\n",
       "      text-decoration: none !important;\n",
       "  }\n",
       "  table.iris {\n",
       "      white-space: pre;\n",
       "      border: 1px solid;\n",
       "      border-color: #9c9c9c;\n",
       "      font-family: monaco, monospace;\n",
       "  }\n",
       "  th.iris {\n",
       "      background: #303f3f;\n",
       "      color: #e0e0e0;\n",
       "      border-left: 1px solid;\n",
       "      border-color: #9c9c9c;\n",
       "      font-size: 1.05em;\n",
       "      min-width: 50px;\n",
       "      max-width: 125px;\n",
       "  }\n",
       "  tr.iris :first-child {\n",
       "      border-right: 1px solid #9c9c9c !important;\n",
       "  }\n",
       "  td.iris-title {\n",
       "      background: #d5dcdf;\n",
       "      border-top: 1px solid #9c9c9c;\n",
       "      font-weight: bold;\n",
       "  }\n",
       "  .iris-word-cell {\n",
       "      text-align: left !important;\n",
       "      white-space: pre;\n",
       "  }\n",
       "  .iris-subheading-cell {\n",
       "      padding-left: 2em !important;\n",
       "  }\n",
       "  .iris-inclusion-cell {\n",
       "      padding-right: 1em !important;\n",
       "  }\n",
       "  .iris-panel-body {\n",
       "      padding-top: 0px;\n",
       "  }\n",
       "  .iris-panel-title {\n",
       "      padding-left: 3em;\n",
       "  }\n",
       "  .iris-panel-title {\n",
       "      margin-top: 7px;\n",
       "  }\n",
       "</style>\n",
       "<table class=\"iris\" id=\"140071909396000\">\n",
       "    <tr class=\"iris\">\n",
       "<th class=\"iris iris-word-cell\">My Constant (m s-1)</th>\n",
       "<th class=\"iris iris-word-cell\">(scalar cube)</th>\n",
       "</tr>\n",
       "    \n",
       "    \n",
       "</table>\n",
       "        "
      ],
      "text/plain": [
       "<iris 'Cube' of my_constant / (m s-1) (scalar cube)>"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ex_const.my_constant"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array(123.456)"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ex_const.my_constant.data"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python [conda env:aeolus_py39]",
   "language": "python",
   "name": "conda-env-aeolus_py39-py"
  },
  "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.9.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
