{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Solving electro-magnetic equations for reflection from glass\n",
    "=================================="
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import sys\n",
    "import os\n",
    "sys.path.append(os.path.dirname(os.getcwd()))\n",
    "import macromax\n",
    "from macromax import log\n",
    "import logging\n",
    "log.setLevel(logging.INFO)  # Comment this line to see more detailed messages\n",
    "\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib notebook"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Define the material properties"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "wavelength = 500e-9\n",
    "source_polarization = np.array([0, 1, 0])[:, np.newaxis]  # y-polarized\n",
    "\n",
    "# Set the sampling grid\n",
    "nb_samples = 1024\n",
    "sample_pitch = wavelength / 16  # overkill, just for display purposes \n",
    "x_range = sample_pitch * np.arange(nb_samples) - 4e-6\n",
    "\n",
    "# define the medium\n",
    "refractive_index = np.ones(len(x_range), dtype=np.complex64)\n",
    "# define an absorbing boundary\n",
    "absorbing_bound = macromax.bound.LinearBound(x_range, thickness=4e-6, max_extinction_coefficient=0.5)\n",
    "# glass has a refractive index of about 1.5, also permittivity and/or permeability can be specified instead\n",
    "refractive_index[(x_range >= 10e-6) & (x_range < 20e-6)] = 1.5"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Define the source"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# point source at 0\n",
    "current_density = np.abs(x_range) < sample_pitch / 4  # A single voxel with j = 1 A / m^2\n",
    "current_density = source_polarization * current_density"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Solve Maxwell's equations"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# The actual work is done here:\n",
    "solution = macromax.solve(x_range, vacuum_wavelength=wavelength, current_density=current_density, refractive_index=refractive_index, bound=absorbing_bound)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Display results"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fig, ax = plt.subplots(2, 1, frameon=False, figsize=(8, 6))\n",
    "\n",
    "x_range = solution.grid[0]  #  coordinates\n",
    "E = solution.E[1, :]  # Electric field\n",
    "H = solution.H[2, :]  # Magnetizing field\n",
    "S = solution.S[0, :]  # Poynting vector\n",
    "f = solution.f[0, :]  # Optical force\n",
    "field_to_display = E  # The source is polarized along this dimension\n",
    "max_val_to_display = np.maximum(np.max(np.abs(field_to_display)), np.finfo(field_to_display.dtype).eps)\n",
    "poynting_normalization = np.max(np.abs(S)) / max_val_to_display\n",
    "ax[0].plot(x_range * 1e6, np.abs(field_to_display)**2 / max_val_to_display, color=[0, 0, 0])[0]\n",
    "ax[0].plot(x_range * 1e6, np.real(S) / poynting_normalization, color=[1, 0, 1])[0]\n",
    "ax[0].plot(x_range * 1e6, np.real(field_to_display), color=[0, 0.7, 0])[0]\n",
    "ax[0].plot(x_range * 1e6, np.imag(field_to_display), color=[1, 0, 0])[0]\n",
    "figure_title = \"Iteration %d, \" % solution.iteration\n",
    "ax[0].set_title(figure_title)\n",
    "ax[0].set_xlabel(\"x  [$\\mu$m]\")\n",
    "ax[0].set_ylabel(\"I, E  [a.u.]\")\n",
    "ax[0].set_xlim(x_range[[0, -1]] * 1e6)\n",
    "\n",
    "ax[1].plot(x_range[-1] * 2e6, 0, color=[0, 0, 0], label='I')\n",
    "ax[1].plot(x_range[-1] * 2e6, 0, color=[1, 0, 1], label='$S_{real}$')\n",
    "ax[1].plot(x_range[-1] * 2e6, 0, color=[0, 0.7, 0], label='$E_{real}$')\n",
    "ax[1].plot(x_range[-1] * 2e6, 0, color=[1, 0, 0], label='$E_{imag}$')\n",
    "ax[1].plot(x_range * 1e6, refractive_index.real, color=[0, 0, 1], label='$n_{real}$')\n",
    "ax[1].plot(x_range * 1e6, refractive_index.imag, color=[0, 0.5, 0.5], label='$n_{imag}$')\n",
    "ax[1].set_xlabel('x  [$\\mu$m]')\n",
    "ax[1].set_ylabel('n')\n",
    "ax[1].set_xlim(x_range[[0, -1]] * 1e6)\n",
    "ax[1].legend(loc='upper right')\n",
    "\n",
    "plt.show()  # Optional\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.6.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
