{ "info": { "author": "Tom Vettenburg", "author_email": "t.vettenburg@dundee.ac.uk", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3", "Topic :: Scientific/Engineering :: Physics" ], "description": "Macroscopic Maxwell Solver\n==========================\n\nIntroduction\n------------\n\nThis Python 3 module enables solving the macroscopic Maxwell equations\nin complex dielectric materials.\n\nThe material properties are defined on a rectangular grid (1D, 2D, or\n3D) for which each voxel defines an isotropic or anistropic\npermittivity. Optionally, a heterogeneous (anisotropic) permeability as\nwell as bi-anisotropic coupling factors may be specified (e.g. for\nchiral media). The source, such as an incident laser field, is specified\nas an oscillating current-density distribution.\n\nThe method iteratively corrects an estimated solution for the electric\nfield (default: all zero). Its memory requirements are on the order of\nthe storage requirements for the material properties and the electric\nfield within the calculation volume. Full details can be found in the\n`open-access `__ manuscript\n`\"Calculating coherent light-wave propagation in large heterogeneous\nmedia.\" `__\n\n**`MIT License `__:\nhttps://opensource.org/licenses/MIT**\n\nInstallation\n------------\n\nPrerequisites\n~~~~~~~~~~~~~\n\n| This library requires Python 3 with the modules ``numpy`` and\n ``scipy`` for the main calculations. These modules will be\n automatically installed.\n| From the core library, the modules ``sys``, ``io``, and ``os`` are\n imported; as well as the modules ``logging`` and ``time`` for\n diagnostics.\n| The ``multiprocessing`` and ``pyfftw`` modules can help speed up the\n calculations.\n\n| The examples require ``matplotlib`` for displaying the results.\n| The ``pypandoc`` module is required for translating this document to\n other formats.\n\nThe code has been tested on Python 3.6.\n\nInstalling\n~~~~~~~~~~\n\nInstalling the ``macromax`` module and its dependencies can be done by\nrunning the following command in a terminal:\n\n.. code:: sh\n\n pip install macromax\n\nThe module comes with a submodule containing example code.\n\n| The ``pypandoc`` module requires the separate installation of\n ``pandoc``. Please refer to:\n| https://pypi.org/project/pypandoc/ for instructions on its\n installation for your operating system of choice.\n\nUsage\n-----\n\nThe basic calculation procedure consists of the following steps:\n\n#. define the material\n\n#. define the coherent light source\n\n#. call ``solution = macromax.solve(...)``\n\n#. display the solution\n\nThe ``macromax`` module must be imported to be able to use the ``solve``\nfunction. The module also contains several utility functions that may\nhelp in defining the property and source distributions.\n\nLoading the Python 3 module\n~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThe ``macromax`` module can be imported using:\n\n.. code:: python\n\n import macromax\n\n| **Optional:**\n| If the module is installed without a package manager, it may not be on\n Python's search path.\n| If necessary, add the library to Python's search path, e.g. using:\n\n.. code:: python\n\n import sys\n import os\n sys.path.append(os.path.dirname(os.getcwd()))\n\nReminder: this library module requires Python 3, ``numpy``, and\n``scipy``. Optionally, ``pyfftw`` can be used to speed up the\ncalculations. The examples also require ``matplotlib``.\n\nSpecifying the material\n~~~~~~~~~~~~~~~~~~~~~~~\n\nDefining the sampling grid\n^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nThe material properties are sampled on a plaid uniform rectangular grid\nof voxels. The sample points are defined by one or more linearly\nincreasing coordinate ranges, one range per dimensions. The coordinates\nmust be specified in meters, e.g.:\n\n.. code:: python\n\n x_range = 50e-9 * np.arange(1000)\n\n| Ranges for multiple dimensions can be passed to ``solve(...)`` as a\n tuple of ranges:\n| ``ranges = (x_range, y_range)``, or the convenience function\n ``utils.calc_ranges`` can be used as follows:\n\n.. code:: python\n\n from macromax import utils\n data_shape = (200, 400)\n sample_pitch = 50e-9 # or (50e-9, 50e-9)\n ranges = utils.calc_ranges(data_shape, sample_pitch)\n\nDefining the material property distributions\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nThe material properties are defined by ndarrays of 2+N dimensions, where\nN can be up to 3 for three-dimensional samples. In each sample point, or\nvoxel, a complex 3x3 matrix defines the anisotropy at that point in the\nsample volume. The first two dimensions of the ndarray are used to store\nthe 3x3 matrix, the following dimensions are the spatial indices x, y,\nand z. Four complex ndarrays can be specified: ``epsilon``, ``mu``,\n``xi``, and ``zeta``. These ndarrays represent the permittivity,\npermeability, and the two coupling factors, respectively.\n\n| When the first two dimensions of a property are found to be both a\n singleton, i.e. 1x1, that property is assumed to be isotropic.\n Similarly, singleton spatial dimensions are interpreted as homogeneity\n in that property.\n| The default permeability ``mu`` is 1, and the coupling contants are\n zero by default.\n\nBoundary conditions\n'''''''''''''''''''\n\n| The underlying algorithm assumes `periodic boundary\n conditions `__.\n| Alternative boundary conditions can be implemented by surrounding the\n calculation area with absorbing (or reflective) layers.\n| Back reflections can be suppressed by e.g. linearly increasing the\n imaginary part of the permittivity with depth into a boundary with a\n thickness of a few wavelengths.\n\nDefining the source\n~~~~~~~~~~~~~~~~~~~\n\n| The coherent source is defined by an oscillating current density, to\n model e.g. an incident laser beam.\n| It is sufficient to define its phase, amplitude, and the direction as\n a function the spatial coordinates; alongside the angular frequency,\n omega, of the coherent source.\n| To avoid issues with numerical precision, the current density is\n multiplied by the angular frequency, omega, and the vacuum\n permeability, mu\\_0. The source values is proportional to the current\n density, J, and related as follows: S = i omega mu\\_0 J with units of\n rad s^-1 H m^-1 A m^-2 = rad V m^-3.\n\nThe source distribution is stored as a complex ndarray with 1+N\ndimensions. The first dimension contains the current 3D direction and\namplitude for each voxel. The complex argument indicates the relative\nphase at each voxel.\n\nCalculating the electromagnetic light field\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nOnce the ``macromax`` module is imported, the solution satisfying the\nmacroscopic Maxwell's equations is calculated by calling:\n\n.. code:: python\n\n solution = macromax.solve(...)\n\nThe function arguments to ``macromax.solve(...)`` can be the following:\n\n- ``x_range|ranges``: A vector (1D) or tuple of vectors (2D, or 3D)\n indicating the spatial coordinates of the sample points. Each vector\n must be a uniformly increasing array of coordinates, sufficiently\n dense to avoid aliasing artefacts.\n\n- ``vacuum_wavelength|wave_number|anguler_frequency``: The wavelength\n in vacuum of the coherent illumination in units of meters.\n\n- ``source_distribution``: An ndarray of complex values indicating the\n source value and direction at each sample point. The source values\n define the current density in the sample. The first dimension\n contains the vector index, the following dimensions contain the\n spatial dimensions.\n\n- ``epsilon``: A complex ndarray that defines the 3x3 permittivity\n matrix at all sample points. The first two dimensions contain the\n matrix indices, the following dimensions contain the spatial\n dimensions.\n\nAnisotropic material properties such as permittivity can be defined as a\nsquare 3x3 matrix at each sample point. Isotropic materials may be\nrepresented by 1x1 scalars instead (the first two dimensions are\nsingletons). Homogeneous materials may be specified with spatial\nsingleton dimensions.\n\nOptionally one can also specify magnetic and coupling factors:\n\n- ``mu``: A complex ndarray that defines the 3x3 permeability matrix at\n all sample points. The first two dimensions contain the matrix\n indices, the following dimensions contain the spatial dimensions.\n\n- ``xi`` and ``zeta``: Complex ndarray that define the 3x3 coupling\n matrices at all sample points. This may be useful to model chiral\n materials. The first two dimensions contain the matrix indices, the\n following dimensions contain the spatial dimensions.\n\nIt is often useful to also specify a callback function that tracks\nprogress. This can be done by defining the ``callback``-argument as a\nfunction that takes an intermediate solution as argument. This\nuser-defined callback function can display the intermediate solution and\ncheck if the convergence is adequate. The callback function should\nreturn ``True`` if more iterations are required, and ``False``\notherwise. E.g.:\n\n.. code:: python\n\n callback=lambda s: s.iteration < 1e4 and s.residue > 1e-4\n\nThe solution object (of the Solution class) fully defines the state of\nthe iteration and the current solution as described below.\n\nThe ``macromax.solve(...)`` function returns a solution object. This\nobject contains the electric field vector distribution as well as\ndiagnostic information such as the number of iterations used and the\nmagnitude of the correction applied in the last iteration. It can also\ncalculate the displacement, magnetizing, and magnetic fields on demand.\nThese fields can be queried as follows:\n\n- ``solution.E``: Returns the electric field distribution.\n- ``solution.H``: Returns the magnetizing field distribution.\n- ``solution.D``: Returns the electric displacement field distribution.\n- ``solution.B``: Returns the magnetic flux density distribution.\n- ``solution.S``: The Poynting vector distribution in the sample.\n\nThe field distributions are returned as complex ``numpy`` ndarrays in\nwhich the first dimensions is the polarization or direction index. The\nfollowing dimensions are the spatial dimensions of the problem, e.g. x,\ny, and z, for three-dimensional problems.\n\nThe solution object also keeps track of the iteration itself. It has the\nfollowing diagnostic properties:\n\n- ``solution.iteration``: The number of iterations performed.\n- ``solution.residue``: The relative magnitude of the correction during\n the previous iteration.\n and it can be used as a Python iterator.\n\nFurther information can be found in the examples and the function and\nclass signature documentation. The examples can be imported using:\n\n.. code:: python\n\n from macromax import examples\n\nComplete Example\n~~~~~~~~~~~~~~~~\n\n| The following code loads the library, defines the material and light\n source, calculates the result, and displays it.\n| To keep this example as simple as possible, the calculation is limited\n to one dimension. Higher dimensional calculations\n| simply require the definition of the material and light source in 2D\n or 3D.\n\nThe first section of the code loads the ``macromax`` library module as\nwell as its ``utils`` submodule. More\n\n.. code:: python\n\n import macromax\n\n import numpy as np\n import scipy.constants as const\n import matplotlib.pyplot as plt\n %matplotlib notebook\n\n #\n # Define the material properties\n #\n wavelength = 500e-9\n angular_frequency = 2 * const.pi * const.c / wavelength\n source_amplitude = 1j * angular_frequency * const.mu_0\n p_source = np.array([0, 1, 0]) # y-polarized\n\n # Set the sampling grid\n nb_samples = 1024\n sample_pitch = wavelength / 16\n x_range = sample_pitch * np.arange(nb_samples) - 4e-6\n\n # define the medium\n permittivity = np.ones((1, 1, len(x_range)), dtype=np.complex64)\n # Don't forget absorbing boundary:\n dist_in_boundary = np.maximum(-(x_range - -1e-6), x_range - 26e-6) / 4e-6\n permittivity[:, :, (x_range < -1e-6) | (x_range > 26e-6)] = \\\n 1.0 + (0.8j * dist_in_boundary[(x_range < -1e-6) | (x_range > 26e-6)])\n # glass has a refractive index of about 1.5\n permittivity[:, :, (x_range >= 10e-6) & (x_range < 20e-6)] = 1.5 ** 2\n\n #\n # Define the illumination source\n #\n # point source at x = 0\n source = -source_amplitude * sample_pitch * (np.abs(x_range) < sample_pitch/4)\n source = p_source[:, np.newaxis] * source[np.newaxis, :]\n\n #\n # Solve Maxwell's equations\n #\n # (the actual work is done in this line)\n solution = macromax.solve(x_range, vacuum_wavelength=wavelength,\n source_distribution=source, epsilon=permittivity)\n\n #\n # Display the results\n #\n fig, ax = plt.subplots(2, 1, frameon=False, figsize=(8, 6))\n\n x_range = solution.ranges[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 # Display the field for the polarization dimension\n field_to_display = angular_frequency * E\n max_val_to_display = np.maximum(np.max(np.abs(field_to_display)),\n 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,\n np.abs(field_to_display) ** 2 / max_val_to_display,\n color=[0, 0, 0])[0]\n ax[0].plot(x_range * 1e6, np.real(S) / poynting_normalization,\n color=[1, 0, 1])[0]\n ax[0].plot(x_range * 1e6, np.real(field_to_display),\n color=[0, 0.7, 0])[0]\n ax[0].plot(x_range * 1e6, np.imag(field_to_display),\n 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,\n color=[0, 0, 0], label='I')\n ax[1].plot(x_range[-1] * 2e6, 0,\n color=[1, 0, 1], label='$S_{real}$')\n ax[1].plot(x_range[-1] * 2e6, 0,\n color=[0, 0.7, 0], label='$E_{real}$')\n ax[1].plot(x_range[-1] * 2e6, 0,\n color=[1, 0, 0], label='$E_{imag}$')\n ax[1].plot(x_range * 1e6, permittivity[0, 0].real,\n color=[0, 0, 1], label='$\\epsilon_{real}$')\n ax[1].plot(x_range * 1e6, permittivity[0, 0].imag,\n color=[0, 0.5, 0.5], label='$\\epsilon_{imag}$')\n ax[1].set_xlabel('x [$\\mu$m]')\n ax[1].set_ylabel('$\\epsilon$, $\\mu$')\n ax[1].set_xlim(x_range[[0, -1]] * 1e6)\n ax[1].legend(loc='upper right')\n\nDevelopment\n-----------\n\nSource code organization\n~~~~~~~~~~~~~~~~~~~~~~~~\n\nThe source code is organized as follows:\n\n- ``/`` (root): Module description and distribution files.\n\n- ``/macromax``: The iterative solver.\n\n- ``/macromax/examples``: Examples of how the solver can be used.\n\n- ``/macromax/tests``: Automated unit tests of the solver's\n functionality. Use this after making modifications to the solver and\n extend it if new functionality is added.\n\nThe library functions are contained in ``/macromax``:\n\n- ``solver``: Defines the ``solve(...)`` function and the ``Solution``\n class.\n\n- ``parallel_ops_column``: Defines linear algebra functions to work\n efficiently with large arrays of 3x3 matrices and 3-vectors.\n\n- ``utils``: Defines utility functions that can be used to prepare and\n interpret function arguments.\n\nThe included examples in the ``/macromax/examples`` folder are:\n\n- ``notebook_example.ipynb``: An iPython notebook demonstrating basic\n usage of the library.\n\n- ``air_glass_air_1D.py``: Calculation of the back reflection from an\n air-glass interface (one-dimensional calculation)\n\n- ``air_glass_air_2D.py``: Calculation of the refraction and reflection\n of light hitting a glass window at an angle (two-dimensional\n calculation)\n\n- ``birefringent_crystal.py``: Demonstration of how an anisotropic\n permittivity can split a diagonally polarized Gaussian beam into\n ordinary and extraordinary beams.\n\n- ``polarizer.py``: Calculation of light wave traversing a set of two\n and a set of three polarizers as a demonstration of anisotropic\n absorption (non-Hermitian permittivity)\n\n- ``rutile.py``: Scattering from disordered collection of birefringent\n rutile (TiO2) particles.\n\nTesting\n~~~~~~~\n\n| Unit tests are contained in ``macromax/tests``. The\n ``ParallelOperations`` class in\n| ``parallel_ops_column.pi`` is pretty well covered and some specific\n tests have been written for\n| the ``Solution`` class in ``solver.py``. However, the ``utils`` module\n does not have any\n| tests at present.\n\nTo run the tests:\n\n.. code:: sh\n\n pip install nose\n python setup.py test\n\nBuilding and Distributing\n~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThe code consists of pure Python 3, hence only packaging is required for\ndistribution.\n\nTo prepare a package for distribution, increase the version number in\n``setup.py``, and run:\n\n.. code:: sh\n\n python setup.py sdist bdist_wheel\n pip install . --upgrade\n\nThe package can then be uploaded to a test repository as follows:\n\n.. code:: sh\n\n twine upload --repository-url https://test.pypi.org/legacy/ dist/*\n\nInstalling from the test repository is done as follows:\n\n.. code:: sh\n\n pip install -i https://test.pypi.org/simple/ macromax\n\nIntelliJ IDEA project files can be found in ``MacroMax/python/``:\n``MacroMax/python/python.iml`` and the folder ``MacroMax/python/.idea``.\n\n\n", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "", "keywords": "light electromagnetic propagation anisotropy magnetic chiral optics Maxwell scattering heterogeneous", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "macromax", "package_url": "https://pypi.org/project/macromax/", "platform": "", "project_url": "https://pypi.org/project/macromax/", "project_urls": null, "release_url": "https://pypi.org/project/macromax/0.0.9/", "requires_dist": [ "numpy", "scipy" ], "requires_python": ">=3", "summary": "Library for solving macroscopic Maxwell's equations for electromagnetic waves in gain-free heterogeneous (bi-)(an)isotropic (non)magnetic materials. This is of particular interest to calculate the light field within complex, scattering, tissues.", "version": "0.0.9" }, "last_serial": 5816895, "releases": { "0.0.6": [ { "comment_text": "", "digests": { "md5": "4e6e641b70ef34bcc0990e810da50c40", "sha256": "7412d7d62dc1451049ac1a2aaad2338df0c24fdf4a7aec8525c2e512c2a6c2e0" }, "downloads": -1, "filename": "macromax-0.0.6-py3-none-any.whl", "has_sig": false, "md5_digest": "4e6e641b70ef34bcc0990e810da50c40", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3", "size": 55908, "upload_time": "2018-12-29T18:33:36", "url": "https://files.pythonhosted.org/packages/d8/91/437bd6248e4aa38a09ee99037dbea9a159083771b6cbc0fc6bfd9cac7225/macromax-0.0.6-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "5c2a42a766012a33ba5115fe9827dada", "sha256": "6b4b699f3b6dd0324361a154d1fe03e9b984d0853b3c4048b6a197998a5a5db9" }, "downloads": -1, "filename": "macromax-0.0.6.tar.gz", "has_sig": false, "md5_digest": "5c2a42a766012a33ba5115fe9827dada", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3", "size": 233429, "upload_time": "2018-12-29T18:33:43", "url": "https://files.pythonhosted.org/packages/79/e7/438b6fddfbb25076bea70a129037ab4310cd1b522719af476589cfacebb5/macromax-0.0.6.tar.gz" } ], "0.0.8": [ { "comment_text": "", "digests": { "md5": "e3f77a785947349c2f857ad0b17a6bc8", "sha256": "79dcf5b65e1e755b1d753b03866518a21fc089f386c5c146995324f86492a91b" }, "downloads": -1, "filename": "macromax-0.0.8-py3-none-any.whl", "has_sig": false, "md5_digest": "e3f77a785947349c2f857ad0b17a6bc8", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3", "size": 56741, "upload_time": "2019-01-17T18:18:33", "url": "https://files.pythonhosted.org/packages/35/61/441c9d0fa9c1ed59f10c8fe6c9384d4774081ab662452bfcaba25449dce6/macromax-0.0.8-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "495784d862cc902367628b98f6f5d0f9", "sha256": "3689ca493a9a4822ce58733d59697cb228598110b93c2712599d313b855f74ba" }, "downloads": -1, "filename": "macromax-0.0.8.tar.gz", "has_sig": false, "md5_digest": "495784d862cc902367628b98f6f5d0f9", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3", "size": 52819, "upload_time": "2019-01-17T18:18:34", "url": "https://files.pythonhosted.org/packages/7e/17/0260b046ba628c37adbe7539bd73781a7624b839822c1ae33cbf883b4984/macromax-0.0.8.tar.gz" } ], "0.0.9": [ { "comment_text": "", "digests": { "md5": "e5027f4bb28532bc5a7d95eb3945085a", "sha256": "8969e1776444b9f96b341c64adc86f848ab0412be18391fdf7caec706e1300d3" }, "downloads": -1, "filename": "macromax-0.0.9-py3-none-any.whl", "has_sig": false, "md5_digest": "e5027f4bb28532bc5a7d95eb3945085a", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3", "size": 61101, "upload_time": "2019-09-11T20:59:43", "url": "https://files.pythonhosted.org/packages/bc/e0/b7b3424d41fbd8f3aa24e77006bf6c34354949624a3a3478b8086db9e06b/macromax-0.0.9-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "fae75ea5a696f1664d16eb5caf127423", "sha256": "f32d217b413b1634475b15e3b381b9e0ad9cc3164ce3fc601d92954ad4dbe67f" }, "downloads": -1, "filename": "macromax-0.0.9.tar.gz", "has_sig": false, "md5_digest": "fae75ea5a696f1664d16eb5caf127423", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3", "size": 51400, "upload_time": "2019-09-11T20:59:45", "url": "https://files.pythonhosted.org/packages/f2/15/91c832b64ad9341d991a8a2ca1e8daafccd44c36056aafed5f2c2a349724/macromax-0.0.9.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "e5027f4bb28532bc5a7d95eb3945085a", "sha256": "8969e1776444b9f96b341c64adc86f848ab0412be18391fdf7caec706e1300d3" }, "downloads": -1, "filename": "macromax-0.0.9-py3-none-any.whl", "has_sig": false, "md5_digest": "e5027f4bb28532bc5a7d95eb3945085a", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3", "size": 61101, "upload_time": "2019-09-11T20:59:43", "url": "https://files.pythonhosted.org/packages/bc/e0/b7b3424d41fbd8f3aa24e77006bf6c34354949624a3a3478b8086db9e06b/macromax-0.0.9-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "fae75ea5a696f1664d16eb5caf127423", "sha256": "f32d217b413b1634475b15e3b381b9e0ad9cc3164ce3fc601d92954ad4dbe67f" }, "downloads": -1, "filename": "macromax-0.0.9.tar.gz", "has_sig": false, "md5_digest": "fae75ea5a696f1664d16eb5caf127423", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3", "size": 51400, "upload_time": "2019-09-11T20:59:45", "url": "https://files.pythonhosted.org/packages/f2/15/91c832b64ad9341d991a8a2ca1e8daafccd44c36056aafed5f2c2a349724/macromax-0.0.9.tar.gz" } ] }