Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scheme tutorial example for add-near2far with periodic boundaries #858

Merged
merged 2 commits into from
May 7, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions doc/docs/Exploiting_Symmetry.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
# Exploiting Symmetry
---

Meep allows you to take advantage of mirror and rotational symmetries in your problem to reduce the amount of computation and storage required for simulation. The use of symmetry is designed to be **transparent**: once you specify the symmetry, Meep exploits it as an internal optimization, while everything else about the simulation *appears* the same as if you didn't specify the symmetry. That is, when you output it still outputs the entire non-symmetrized cell, you can still call `get_field_point` to obtain the fields at any point, etcetera — internally, Meep transforms everything as necessary according to the symmetries to get whatever data is needed.
Meep allows you to take advantage of mirror and rotational symmetries in your problem to reduce the amount of computation and storage required for simulation. The use of symmetry is designed to be **transparent**: once you specify the symmetry, Meep exploits it as an internal optimization, while everything else about the simulation *appears* the same as if you didn't specify the symmetry. That is, when you output the structure/geometry or currents/fields it still outputs the entire non-symmetrized cell; you can still call `get_field_point` to obtain the fields at any point, etcetera — internally, Meep transforms everything as necessary according to the symmetries to get whatever data is needed.

An important point to understand is that, when you specify a symmetry, it must be obeyed by *both* the structure/geometry *and* by the current sources and thus the fields. In particular, the symmetry of the currents/fields will typically require you to specify *phase factors* associated with the symmetry operations — for example, a mirror plane can either be used for *even* sources/fields (phase +1) or for *odd* sources/fields (phase −1).
An important point to understand is that, when you specify a symmetry, it must be obeyed by **both** the structure/geometry **and** by the current sources and thus the fields. In particular, the symmetry of the currents/fields will typically require you to specify *phase factors* associated with the symmetry operations — for example, a mirror plane can either be used for *even* sources/fields (phase +1) or for *odd* sources/fields (phase −1).

**Meep does not check whether the symmetry is obeyed**. If you specify a symmetry that does not preserve your structure/sources, then the results are undefined.

Expand All @@ -20,10 +20,14 @@ Meep supports exploiting several kinds of symmetries:
### Rotations and Reflections

- Mirror planes through the origin, and normal to the $x$/$y$/$z$ axes.
- 180° rotational symmetry about the origin, around the $x$/$y$/$z$ axes. This is also known as a $C_2$ symmetry, in group theory. This is different from a mirror plane: e.g. the letter "S" has $C_2$ but not mirror symmetry.
- 180° rotational symmetry about the origin, around the $x$/$y$/$z$ axes. This is also known as a $C_2$ symmetry, in group theory. This is different from a mirror plane: e.g. as shown in the figure below, the letter "S" has $C_2$ but not mirror symmetry.
- 90° (fourfold) rotational symmetry about the origin, around the $x$/$y$/$z$ axes. This is also known as a $C_4$ symmetry.

The first two kinds of symmetry each reduce the computational cell (internally) by a factor of two, and the third by a factor of four. If your structure has multiple symmetries, you can combine them arbitrarily. For example, your cell may have two orthogonal mirror planes (e.g. one even and one odd), or it may have four-fold rotational symmetry about the $z$ axis and a mirror plane through $z=0$. Thus, in 3d you might be able to reduce your cell by at most a factor of eight, or a factor of four in 2d. This is why the interface lets you specify a *list* `symmetries` of `symmetry` objects.
<center>
![](../images/C2_symmetry.png)
</center>

The first two kinds of symmetry each reduce the computational cell (internally) by a factor of two, and the third by a factor of four. If your structure has multiple symmetries, you can combine them arbitrarily. For example, your cell may have two orthogonal mirror planes (e.g. one even and one odd), or it may have four-fold rotational symmetry about the $z$ axis and a mirror plane through $z=0$. Thus, in 3d you might be able to reduce your cell by at most a factor of eight, or a factor of four in 2d. This is why the interface lets you specify a **list** `symmetries` of `symmetry` objects.

There are also two other kinds of symmetry you can exploit.

Expand All @@ -43,9 +47,9 @@ In a cylindrical simulation, fields can be written in the form of a function of

### Translational Symmetry

If the structure has discrete or continuous translational symmetry in some direction, then this is handled in Meep by specifying periodic boundary conditions in that direction. Here, the fields/sources take the form of $\exp(i\mathbf{k}\cdot\mathbf{x})$ multiplied by a periodic envelope, so one specifies **Bloch-periodic** boundary conditions with a given Bloch wavevector $\mathbf{k}$.
If the structure has discrete or continuous translational symmetry in some direction, then this is handled in Meep by specifying periodic boundary conditions in that direction. Here, the currents/fields take the form of $\exp(i\mathbf{k}\cdot\mathbf{x})$ multiplied by a periodic envelope, so one specifies **Bloch-periodic** boundary conditions with a given Bloch wavevector $\mathbf{k}$.

For example, to simulate the modes of a uniform waveguide (continuous translational symmetry) in the $x$ direction, one would specify a structure with `no-size` in the $x$ direction and a given $k_x$ corresponding to the wavenumber of the desired mode. For discrete periodicity, see [Tutorial/Resonant Modes and Transmission in a Waveguide Cavity/Band Diagram](Python_Tutorials/Resonant_Modes_and_Transmission_in_a_Waveguide_Cavity.md#band-diagram).
For example, to simulate the modes of a uniform waveguide (continuous translational symmetry) in the $x$ direction, one would specify a structure with 0 cell-size (Python) or `no-size` (Scheme) in the $x$ direction and a given $k_x$ corresponding to the wavenumber of the desired mode. For discrete periodicity, see [Tutorial/Resonant Modes and Transmission in a Waveguide Cavity/Band Diagram](Python_Tutorials/Resonant_Modes_and_Transmission_in_a_Waveguide_Cavity.md#band-diagram).

Symmetry Phase Factors
----------------------
Expand All @@ -58,7 +62,7 @@ As a specific example, suppose the structure is even in *y*. In this case, an E<

The phase factors are ignored when applying the symmetry to the structure (e.g. to ε.)

Technically, the symmetry operations that preserve the structure form the symmetry group. In particular, this is a point group or, if you include translations, the space group of the structure. The phase factors specify the *representation* of the group that the fields/sources transform as. See also any book on group theory in physics, e.g. [Group Theory and Its Applications in Physics](http://www.springer.com/us/book/9783540604457) by Inui, Tanabe, and Onodera.
Technically, the symmetry operations that preserve the structure form the [symmetry group](https://en.wikipedia.org/wiki/Symmetry_group). In particular, this is a [point group](https://en.wikipedia.org/wiki/Point_group) or, if you include translations, the [space group](https://en.wikipedia.org/wiki/Space_group) of the structure. The phase factors specify the *representation* of the group that the fields/sources transform as. See also any book on group theory in physics, e.g. [Group Theory and Its Applications in Physics](http://www.springer.com/us/book/9783540604457) by Inui, Tanabe, and Onodera.

Vectors and Pseudovectors
-------------------------
Expand Down
8 changes: 4 additions & 4 deletions doc/docs/Python_Tutorials/Mode_Decomposition.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,13 +143,13 @@ The reflectance values computed using the two methods are nearly identical. For
Diffraction Spectrum of a Binary Grating
----------------------------------------

The mode-decomposition feature can also be applied to planewaves in homogeneous media with scalar permittivity/permeability (i.e., no anisotropy). This will be demonstrated in this example to compute the diffraction spectrum of a binary phase [grating](https://en.wikipedia.org/wiki/Diffraction_grating). (An alternative method, which is much more inefficient, involves computing the near-to-far field transformation as demonstrated in [Tutorials/Near to Far Field Spectra/Diffraction Spectrum of a Binary Grating](Near_to_Far_Field_Spectra.md#diffraction-spectrum-of-a-binary-grating).) The unit cell geometry of the grating is shown in the schematic below. The grating is periodic in the $y$ direction with periodicity `gp` and has a rectangular profile of height `gh` and duty cycle `gdc`. The grating parameters are `gh`=0.5 μm, `gdc`=0.5, and `gp`=10 μm. There is a semi-infinite substrate of thickness `dsub` adjacent to the grating. The substrate and grating are glass with a refractive index of 1.5. The surrounding is air/vacuum. Perfectly matched layers (PML) of thickness `dpml` are used in the $\pm x$ boundaries.
The mode-decomposition feature can also be applied to planewaves in homogeneous media with scalar permittivity/permeability (i.e., no anisotropy). This will be demonstrated in this example to compute the diffraction spectrum of a binary phase [grating](https://en.wikipedia.org/wiki/Diffraction_grating). To compute the diffraction spectrum for a finite-length structure, see [Tutorials/Near to Far Field Spectra/Diffraction Spectrum of a Finite Binary Grating](Near_to_Far_Field_Spectra.md#diffraction-spectrum-of-a-finite-binary-grating). The unit cell geometry of the grating is shown in the schematic below. The grating is periodic in the $y$ direction with periodicity `gp` and has a rectangular profile of height `gh` and duty cycle `gdc`. The grating parameters are `gh`=0.5 μm, `gdc`=0.5, and `gp`=10 μm. There is a semi-infinite substrate of thickness `dsub` adjacent to the grating. The substrate and grating are glass with a refractive index of 1.5. The surrounding is air/vacuum. Perfectly matched layers (PML) of thickness `dpml` are used in the $\pm x$ boundaries.

### Transmittance Spectra for Planewave at Normal Incidence

A pulsed planewave with E<sub>z</sub> polarization spanning wavelengths of 0.4 to 0.6 μm is normally incident on the grating from the glass substrate. The eigenmode monitor is placed in the air region. We will use mode decomposition to compute the transmittance &mdash; the ratio of the power in the $+x$ direction of the diffracted mode relative to that of the incident planewave &mdash; for the first ten diffraction orders. Two simulations are required: (1) an *empty* cell of homogeneous glass to obtain the incident power of the source, and (2) the grating structure to obtain the diffraction orders. At the end of the simulation, the wavelength, angle, and transmittance for each diffraction order are computed.

The simulation script is in [examples/binary_grating.py](https://github.com/NanoComp/meep/blob/master/python/examples/binary_grating.py). The notebook is [examples/binary_grating.ipynb](https://nbviewer.jupyter.org/github/NanoComp/meep/blob/master/python/examples/binary_grating.ipynb)
The simulation script is in [examples/binary_grating.py](https://github.com/NanoComp/meep/blob/master/python/examples/binary_grating.py). The notebook is [examples/binary_grating.ipynb](https://nbviewer.jupyter.org/github/NanoComp/meep/blob/master/python/examples/binary_grating.ipynb).

<center>
![](../images/grating.png)
Expand Down Expand Up @@ -280,7 +280,7 @@ The diffraction orders/modes are a finite set of propagating planewaves. The wav
![](../images/grating_diffraction_spectra.png)
</center>

In the limit where the grating periodicity is much larger than the wavelength and the size of the diffracting element (i.e., more than 10 times), as it is in this example, the [diffraction efficiency](https://en.wikipedia.org/wiki/Diffraction_efficiency) can be computed analytically using scalar theory. This is described in the OpenCourseWare [Optics course](https://ocw.mit.edu/courses/mechanical-engineering/2-71-optics-spring-2009/) in the Lecture 16 (Gratings: Amplitude and Phase, Sinusoidal and Binary) [notes](https://ocw.mit.edu/courses/mechanical-engineering/2-71-optics-spring-2009/video-lectures/lecture-16-gratings-amplitude-and-phase-sinusoidal-and-binary/MIT2_71S09_lec16.pdf) and [video](https://www.youtube.com/watch?v=JmWguqCZRxk). For a review of scalar diffraction theory, see Chapter 3 ("Analysis of Two-Dimensional Signals and Systems") of [Introduction to Fourier Optics (fourth edition)](https://www.amazon.com/Introduction-Fourier-Optics-Joseph-Goodman-ebook/dp/B076TBP48F) by J.W. Goodman. From the scalar theory, the diffraction efficiency of the binary grating is 4/(mπ)<sup>2</sup> when the phase difference between the propagating distance in the glass relative to the same distance in air is π. The phase difference/contrast is (2π/λ)(n-1)s where λ is the wavelength, n is the refractive index of the grating, and s is the propagation distance in the grating (`gh` in the script). A special feature of the binary grating is that the diffraction efficiency is 0 for all *even* orders. This is verified by the diffraction spectrum shown above.
In the limit where the grating periodicity is much larger than the wavelength and the size of the diffracting element (i.e., more than 10 times), as it is in this example, the [diffraction efficiency](https://en.wikipedia.org/wiki/Diffraction_efficiency) can be computed analytically using scalar theory. This is described in the OpenCourseWare [Optics course](https://ocw.mit.edu/courses/mechanical-engineering/2-71-optics-spring-2009/) in the Lecture 16 (Gratings: Amplitude and Phase, Sinusoidal and Binary) [notes](https://ocw.mit.edu/courses/mechanical-engineering/2-71-optics-spring-2009/video-lectures/lecture-16-gratings-amplitude-and-phase-sinusoidal-and-binary/MIT2_71S09_lec16.pdf) and [video](https://www.youtube.com/watch?v=JmWguqCZRxk). For a review of scalar diffraction theory, see Chapter 3 ("Analysis of Two-Dimensional Signals and Systems") of [Introduction to Fourier Optics (fourth edition)](https://www.amazon.com/Introduction-Fourier-Optics-Joseph-Goodman-ebook/dp/B076TBP48F) by J.W. Goodman. From the scalar theory, the diffraction efficiency of the binary grating is 4/(mπ)<sup>2</sup> when the phase difference between the propagating distance in the glass relative to the same distance in air is π. The phase difference/contrast is (2π/λ)(n-1)s where λ is the wavelength, n is the refractive index of the grating, and s is the propagation distance in the grating (`gh` in the script). A special feature of the binary grating is that the diffraction efficiency is 0 for all *even* orders. This is verified by the diffraction spectrum shown above. Also, since the diffraction efficiency of the ninth order has already fallen to a negligible value (~0.005), computing the spectra of higher-order modes is unnecessary.

To convert the diffraction efficiency into transmittance in the *x* direction (in order to be able to compare the scalar-theory results with those from Meep), the diffraction efficiency must be multiplied by the Fresnel transmittance from air to glass and by the cosine of the diffraction angle. We compare the analytic and simulated results at a wavelength of 0.5 μm for diffraction orders 1 (2.9°), 3 (8.6°), 5 (14.5°), and 7 (20.5°). The analytic results are 0.3886, 0.0427, 0.0151, and 0.0074. The Meep results are 0.3891, 0.04287, 0.0152, and 0.0076. This corresponds to relative errors of approximately 1.3%, 0.4%, 0.8%, and 2.1% which indicates good agreement.

Expand All @@ -292,7 +292,7 @@ The following script is adapted from the previous binary-grating example involvi

Results are computed for a single wavelength of 0.5 μm. The pulsed planewave is incident at an angle of 10.7°. Its spatial profile is defined using the source amplitude function `pw_amp`. This [anonymous function](https://en.wikipedia.org/wiki/Anonymous_function) takes two arguments, the wavevector and a point in space (both `mp.Vector3`s), and returns a function of one argument which defines the planewave amplitude at that point. A narrow bandwidth pulse is used in order to mitigate the intrinsic discretization effects of the [Yee grid](../Yee_Lattice.md) for oblique planewaves. Also, the `stop_when_fields_decayed` termination criteria is replaced with `until_after_sources`. As a general rule of thumb, the more oblique the planewave source, the longer the run time required to ensure accurate results. There is an additional line monitor between the source and the grating for computing the reflectance. The angle of each reflected/transmitted mode, which can be positive or negative, is computed using its dominant planewave vector. Since the oblique source breaks the symmetry in the $y$ direction, each diffracted order must be computed separately. In total, there are 59 reflected and 39 transmitted orders.

The simulation script is in [examples/binary_grating_oblique.py](https://github.com/NanoComp/meep/blob/master/python/examples/binary_grating_oblique.py). The notebook is [examples/binary_grating_oblique.ipynb](https://nbviewer.jupyter.org/github/NanoComp/meep/blob/master/python/examples/binary_grating_oblique.ipynb)
The simulation script is in [examples/binary_grating_oblique.py](https://github.com/NanoComp/meep/blob/master/python/examples/binary_grating_oblique.py). The notebook is [examples/binary_grating_oblique.ipynb](https://nbviewer.jupyter.org/github/NanoComp/meep/blob/master/python/examples/binary_grating_oblique.ipynb).

```py
import meep as mp
Expand Down
Loading