Skip to content

Commit

Permalink
Add materials_librar.py to python package (NanoComp#479)
Browse files Browse the repository at this point in the history
  • Loading branch information
ChristopherHogan authored and stevengj committed Aug 28, 2018
1 parent 851b19e commit 59103f9
Show file tree
Hide file tree
Showing 8 changed files with 23 additions and 40 deletions.
8 changes: 3 additions & 5 deletions doc/docs/Materials.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,18 +119,16 @@ All of the above features that are supported for the electric permittivity ε ar
Materials Library
-----------------

A materials library is available for [Python](https://github.com/stevengj/meep/tree/master/python/examples/materials_library.py) and [Scheme](https://github.com/stevengj/meep/tree/master/scheme/examples/materials-library.scm) containing [crystalline silicon](https://en.wikipedia.org/wiki/Crystalline_silicon), [amorphous silicon](https://en.wikipedia.org/wiki/Amorphous_silicon) (including hydrogenated), [silicon dioxide](https://en.wikipedia.org/wiki/Silicon_dioxide) (SiO<sub>2</sub>), [indium tin oxide](https://en.wikipedia.org/wiki/Indium_tin_oxide) (ITO), [alumina](https://en.wikipedia.org/wiki/Aluminium_oxide) (Al<sub>2</sub>O<sub>3</sub>), [gallium arsenide](https://en.wikipedia.org/wiki/Gallium_arsenide) (GaAs), [aluminum arsenide](https://en.wikipedia.org/wiki/Aluminium_arsenide) (AlAs), [aluminum nitride](https://en.wikipedia.org/wiki/Aluminium_nitride) (AlN), [borosilicate glass](https://en.wikipedia.org/wiki/Borosilicate_glass) (BK7), [fused quartz](https://en.wikipedia.org/wiki/Fused_quartz), [silicon nitride](https://en.wikipedia.org/wiki/Silicon_nitride) (Si<sub>3</sub>N<sub>4</sub>), [germanium](https://en.wikipedia.org/wiki/Germanium) (Ge), [indium phosphide](https://en.wikipedia.org/wiki/Indium_phosphide) (InP), [poly(methyl methacrylate)](https://en.wikipedia.org/wiki/Poly(methyl_methacrylate)), [polycarbonate](https://en.wikipedia.org/wiki/Polycarbonate), [polystyrene](https://en.wikipedia.org/wiki/Polystyrene), [cellulose](https://en.wikipedia.org/wiki/Cellulose), as well as 11 elemental metals: [silver](https://en.wikipedia.org/wiki/Silver) (Ag), [gold](https://en.wikipedia.org/wiki/Gold) (Au), [copper](https://en.wikipedia.org/wiki/Copper) (Cu), [aluminum](https://en.wikipedia.org/wiki/Aluminium) (Al), [berylium](https://en.wikipedia.org/wiki/Beryllium) (Be), [chromium](https://en.wikipedia.org/wiki/Chromium) (Cr), [nickel](https://en.wikipedia.org/wiki/Nickel) (Ni), [palladium](https://en.wikipedia.org/wiki/Palladium) (Pd), [platinum](https://en.wikipedia.org/wiki/Platinum) (Pt), [titanium](https://en.wikipedia.org/wiki/Titanium) (Ti), and [tungsten](https://en.wikipedia.org/wiki/Tungsten) (W).
A materials library is available for [Python](https://github.com/stevengj/meep/tree/master/python/materials_library.py) and [Scheme](https://github.com/stevengj/meep/tree/master/scheme/examples/materials-library.scm) containing [crystalline silicon](https://en.wikipedia.org/wiki/Crystalline_silicon), [amorphous silicon](https://en.wikipedia.org/wiki/Amorphous_silicon) (including hydrogenated), [silicon dioxide](https://en.wikipedia.org/wiki/Silicon_dioxide) (SiO<sub>2</sub>), [indium tin oxide](https://en.wikipedia.org/wiki/Indium_tin_oxide) (ITO), [alumina](https://en.wikipedia.org/wiki/Aluminium_oxide) (Al<sub>2</sub>O<sub>3</sub>), [gallium arsenide](https://en.wikipedia.org/wiki/Gallium_arsenide) (GaAs), [aluminum arsenide](https://en.wikipedia.org/wiki/Aluminium_arsenide) (AlAs), [aluminum nitride](https://en.wikipedia.org/wiki/Aluminium_nitride) (AlN), [borosilicate glass](https://en.wikipedia.org/wiki/Borosilicate_glass) (BK7), [fused quartz](https://en.wikipedia.org/wiki/Fused_quartz), [silicon nitride](https://en.wikipedia.org/wiki/Silicon_nitride) (Si<sub>3</sub>N<sub>4</sub>), [germanium](https://en.wikipedia.org/wiki/Germanium) (Ge), [indium phosphide](https://en.wikipedia.org/wiki/Indium_phosphide) (InP), [poly(methyl methacrylate)](https://en.wikipedia.org/wiki/Poly(methyl_methacrylate)), [polycarbonate](https://en.wikipedia.org/wiki/Polycarbonate), [polystyrene](https://en.wikipedia.org/wiki/Polystyrene), [cellulose](https://en.wikipedia.org/wiki/Cellulose), as well as 11 elemental metals: [silver](https://en.wikipedia.org/wiki/Silver) (Ag), [gold](https://en.wikipedia.org/wiki/Gold) (Au), [copper](https://en.wikipedia.org/wiki/Copper) (Cu), [aluminum](https://en.wikipedia.org/wiki/Aluminium) (Al), [berylium](https://en.wikipedia.org/wiki/Beryllium) (Be), [chromium](https://en.wikipedia.org/wiki/Chromium) (Cr), [nickel](https://en.wikipedia.org/wiki/Nickel) (Ni), [palladium](https://en.wikipedia.org/wiki/Palladium) (Pd), [platinum](https://en.wikipedia.org/wiki/Platinum) (Pt), [titanium](https://en.wikipedia.org/wiki/Titanium) (Ti), and [tungsten](https://en.wikipedia.org/wiki/Tungsten) (W).

Experimental values of the complex refractive index are fit to a [Drude-Lorentz susceptibility profile](#material-dispersion) over various wavelength ranges. For example, the fit for crystalline silicon is based on [Progress in Photovoltaics, Vol. 3, pp. 189-92, 1995](https://onlinelibrary.wiley.com/doi/full/10.1002/pip.4670030303) for the wavelength range of 0.4 to 1.0 µm as described in [J. Optical Society of America A, Vol. 28, pp. 770-77, 2011](https://www.osapublishing.org/josaa/abstract.cfm?uri=josaa-28-5-770). The fit for the elemental metals is over the range of 0.2 to 12.4 μm and is described in [Applied Optics, Vol. 37, pp. 5271-83, 1998](https://www.osapublishing.org/ao/abstract.cfm?uri=ao-37-22-5271).

Fitting parameters for all materials are defined for a unit distance of 1 µm. For simulations which use a different value for the unit distance, the predefined variable `um_scale` (Python) or `um-scale` (Scheme) must be scaled by *multiplying* by whatever the unit distance is, in units of µm. For example, if the unit distance is 100 nm, this would require adding the line `um_scale = 0.1*um_scale` after the line where [`um_scale` is defined](https://github.com/stevengj/meep/blob/master/python/examples/materials_library.py#L7). This change must be made directly to the materials library file.
Fitting parameters for all materials are defined for a unit distance of 1 µm. For simulations which use a different value for the unit distance, the predefined variable `um_scale` (Python) or `um-scale` (Scheme) must be scaled by *multiplying* by whatever the unit distance is, in units of µm. For example, if the unit distance is 100 nm, this would require adding the line `um_scale = 0.1*um_scale` after the line where [`um_scale` is defined](https://github.com/stevengj/meep/blob/master/python/materials_library.py#L7). This change must be made directly to the materials library file.

As an example, to import aluminum from the library into a Python script requires adding the following lines:

```python
import sys
sys.path.insert(0, '/path/to/materials_library/')
from materials_library import Al
from meep.materials_library import Al
```
Then, the material can be simply used as `geometry = [meep.Cylinder(material=Al, ...]`.

Expand Down
7 changes: 2 additions & 5 deletions doc/docs/Python_Tutorials/Material_Dispersion.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,15 @@ The wavelength-dependent, lossless permittivity of fused quartz, measured experi

$$\varepsilon(\lambda) = 1 + \frac{0.6961663\lambda^2}{\lambda^2-0.0684043^2} + \frac{0.4079426\lambda^2}{\lambda^2-0.1162414^2} + \frac{0.8974794\lambda^2}{\lambda^2-9.896161^2}$$

The wavelength λ is in units of microns. This equation is valid from 0.21 to 6.7 μm. The Sellmeier form for the permittivity of fused quartz can be imported into Meep as a [Lorentzian susceptibility](Materials/#material-dispersion) via a slight reorganization to convert the wavelength dependence into frequency. This is implemented in the [materials library](https://github.com/stevengj/meep/blob/master/python/examples/materials_library.py#L165-L181).
The wavelength λ is in units of microns. This equation is valid from 0.21 to 6.7 μm. The Sellmeier form for the permittivity of fused quartz can be imported into Meep as a [Lorentzian susceptibility](Materials/#material-dispersion) via a slight reorganization to convert the wavelength dependence into frequency. This is implemented in the [materials library](https://github.com/stevengj/meep/blob/master/python/materials_library.py#L165-L181).

The simulation involves a 1d cell. A planewave current source with a pulsed profile spanning visible wavelengths of 0.4 to 0.8 μm is normally incident on the fused quartz from air. The reflectance is computed using the convention of two separate runs: (1) an empty cell to obtain the incident power, and (2) with the fused quartz to obtain the reflected power. The details of this type of calculation are described in [Tutorial/Basics](Basics/#transmittance-spectrum-of-a-waveguide-bend). The grid resolution, and by direct extension the time resolution via the [Courant condition](https://en.wikipedia.org/wiki/Courant%E2%80%93Friedrichs%E2%80%93Lewy_condition), must be made sufficiently fine to obtain agreement with the analytic results and to ensure [numerical stability](Materials/#numerical-stability). Coarse resolutions may lead to field instabilities.

The simulation script is below and in [refl-quartz.py](https://github.com/stevengj/meep/blob/master/python/examples/refl-quartz.py).

```py
import meep as mp

import sys
sys.path.insert(0, '/path/to/materials_library/')
from materials_library import *
from meep.materials_library import fused_quartz

resolution = 200 # pixels/μm

Expand Down
15 changes: 8 additions & 7 deletions python/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ HPPFILES= \
$(top_srcdir)/libmeepgeom/material_data.hpp

BUILT_SOURCES = meep-python.cpp mpb-python.cpp __init__.py mpb.py
EXTRA_DIST = $(BUILT_SOURCES) typemap_utils.cpp solver.py mpb_data.py examples tests
EXTRA_DIST = $(BUILT_SOURCES) typemap_utils.cpp solver.py mpb_data.py materials_library.py examples tests

CLEANFILES = $(BUILT_SOURCES) meep.py

Expand Down Expand Up @@ -81,7 +81,7 @@ TESTS_ENVIRONMENT = export PYTHONPATH=$(abs_top_builddir)/python:$$PYTHONPATH;

if WITH_PYTHON
pympbdir = $(pkgpythondir)/mpb
pkgpython_PYTHON = geom.py __init__.py source.py simulation.py
pkgpython_PYTHON = geom.py __init__.py source.py simulation.py materials_library.py
pkgpyexec_LTLIBRARIES = _meep.la
pympb_DATA = mpb.py solver.py mpb_data.py
pympb_LTLIBRARIES = _mpb.la
Expand Down Expand Up @@ -130,11 +130,12 @@ MPB_PY = $(srcdir)/mpb.py

endif # MAINTAINER_MODE

PY_PKG_FILES = \
$(INIT_PY) \
$(srcdir)/geom.py \
$(srcdir)/simulation.py \
$(srcdir)/source.py \
PY_PKG_FILES = \
$(INIT_PY) \
$(srcdir)/geom.py \
$(srcdir)/simulation.py \
$(srcdir)/source.py \
$(srcdir)/materials_library.py \
.libs/_meep.so

meep: _meep.la _mpb.la __init__.py
Expand Down
3 changes: 1 addition & 2 deletions python/examples/absorber-1d.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
from __future__ import division

import argparse
import math
import meep as mp
from meep.materials_library import Al

from materials_library import *

def main(args):

Expand Down
11 changes: 4 additions & 7 deletions python/examples/refl-quartz.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
# -*- coding: utf-8 -*-

import meep as mp

import sys
sys.path.insert(0, '/path/to/materials_library/')
from materials_library import *
from meep.materials_library import fused_quartz

resolution = 200 # pixels/μm

Expand All @@ -20,7 +17,7 @@
fcen = 0.5*(fmax+fmin)
df = fmax-fmin
nfreq = 50

sources = [ mp.Source(mp.GaussianSource(fcen,fwidth=df), component=mp.Ex, center=mp.Vector3(0,0,-0.5*sz+dpml)) ]

sim = mp.Simulation(cell_size=cell_size,
Expand All @@ -37,7 +34,7 @@
empty_flux = mp.get_fluxes(refl)
empty_data = sim.get_flux_data(refl)
sim.reset_meep()

geometry = [ mp.Block(mp.Vector3(mp.inf,mp.inf,0.5*sz), center=mp.Vector3(0,0,0.25*sz), material=fused_quartz) ]

sim = mp.Simulation(cell_size=cell_size,
Expand All @@ -49,7 +46,7 @@

refl = sim.add_flux(fcen, df, nfreq, refl_fr)
sim.load_minus_flux_data(refl, empty_data)

sim.run(until_after_sources=mp.stop_when_fields_decayed(50, mp.Ex, mp.Vector3(), 1e-9))

refl_flux = mp.get_fluxes(refl)
Expand Down
File renamed without changes.
9 changes: 2 additions & 7 deletions python/tests/absorber_1d.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
from __future__ import division

import math
import unittest
import meep as mp
from meep.materials_library import Al

import os
import sys
matlib_dir = os.path.join(os.path.abspath(os.path.realpath(os.path.dirname(__file__))),
'..', 'examples')
sys.path.insert(0, matlib_dir)
from materials_library import *

class TestAbsorber(unittest.TestCase):

Expand Down Expand Up @@ -57,5 +51,6 @@ def test_absorber_2d(self):

self.assertAlmostEqual(-4.058476603571745e-11, p.real)


if __name__ == '__main__':
unittest.main()
10 changes: 3 additions & 7 deletions python/tests/simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,6 @@
unicode = str


examples_dir = os.path.realpath(os.path.join(os.path.dirname(__file__), '..', 'examples'))
sys.path.insert(0, examples_dir)


class TestSimulation(unittest.TestCase):

fname = 'simulation-ez-000200.00.h5'
Expand Down Expand Up @@ -482,10 +478,10 @@ def test_epsilon_warning(self):

with warnings.catch_warnings(record=True) as w:
warnings.simplefilter("always")
from materials_library import Si
from meep.materials_library import Si
self.assertEqual(len(w), 0)

from materials_library import Mo
from meep.materials_library import Mo
geom = [mp.Sphere(radius=0.2, material=Mo)]
sim = self.init_simple_simulation(geometry=geom)
with warnings.catch_warnings(record=True) as w:
Expand All @@ -494,7 +490,7 @@ def test_epsilon_warning(self):
self.assertGreater(len(w), 0)
self.assertIn("Epsilon", str(w[0].message))

from materials_library import SiO2
from meep.materials_library import SiO2
geom = [mp.Sphere(radius=0.2, material=SiO2)]
sim = self.init_simple_simulation(geometry=geom)
with warnings.catch_warnings(record=True) as w:
Expand Down

0 comments on commit 59103f9

Please sign in to comment.