From 6d38e010fea1fb18d8cc801fa23ee5acf1652982 Mon Sep 17 00:00:00 2001
From: JE Touma <70023515+jamesetouma@users.noreply.github.com>
Date: Sat, 30 Jul 2022 15:54:36 -0500
Subject: [PATCH] Fix html md issues (#2181)
* Add #center to all the images; Center equations
* Update extra.css
---
doc/docs/C++_Tutorial.md | 2 +-
doc/docs/Exploiting_Symmetry.md | 2 +-
doc/docs/FAQ.md | 14 ++++----
doc/docs/Introduction.md | 12 +++----
doc/docs/Materials.md | 6 ++--
doc/docs/Parallel_Meep.md | 18 +++++------
doc/docs/Perfectly_Matched_Layer.md | 6 ++--
doc/docs/Python_Developer_Information.md | 4 +--
doc/docs/Python_Tutorials/Basics.md | 30 ++++++++---------
doc/docs/Python_Tutorials/Custom_Source.md | 10 +++---
.../Cylindrical_Coordinates.md | 12 +++----
doc/docs/Python_Tutorials/Eigenmode_Source.md | 18 +++++------
.../Frequency_Domain_Solver.md | 2 +-
doc/docs/Python_Tutorials/GDSII_Import.md | 12 +++----
doc/docs/Python_Tutorials/Gyrotropic_Media.md | 4 +--
.../Local_Density_of_States.md | 4 +--
.../Python_Tutorials/Material_Dispersion.md | 10 +++---
.../Python_Tutorials/Mode_Decomposition.md | 20 ++++++------
.../Multilevel_Atomic_Susceptibility.md | 6 ++--
.../Near_to_Far_Field_Spectra.md | 26 +++++++--------
doc/docs/Python_Tutorials/Optical_Forces.md | 4 +--
..._and_Transmission_in_a_Waveguide_Cavity.md | 28 ++++++++--------
.../Third_Harmonic_Generation.md | 4 +--
doc/docs/Python_User_Interface.md | 6 ++--
doc/docs/Scheme_Tutorials/Basics.md | 32 +++++++++----------
doc/docs/Scheme_Tutorials/Casimir_Forces.md | 22 ++++++-------
doc/docs/Scheme_Tutorials/Custom_Source.md | 6 ++--
.../Cylindrical_Coordinates.md | 12 +++----
doc/docs/Scheme_Tutorials/Eigenmode_Source.md | 18 +++++------
.../Frequency_Domain_Solver.md | 2 +-
doc/docs/Scheme_Tutorials/Gyrotropic_Media.md | 4 +--
.../Local_Density_of_States.md | 2 +-
.../Scheme_Tutorials/Material_Dispersion.md | 10 +++---
.../Scheme_Tutorials/Mode_Decomposition.md | 18 +++++------
.../Multilevel_Atomic_Susceptibility.md | 6 ++--
.../Near_to_Far_Field_Spectra.md | 20 ++++++------
doc/docs/Scheme_Tutorials/Optical_Forces.md | 4 +--
..._and_Transmission_in_a_Waveguide_Cavity.md | 20 ++++++------
.../Third_Harmonic_Generation.md | 4 +--
doc/docs/Subpixel_Smoothing.md | 10 +++---
doc/docs/Yee_Lattice.md | 4 +--
doc/docs/css/extra.css | 2 +-
doc/docs/index.md | 2 +-
43 files changed, 229 insertions(+), 229 deletions(-)
diff --git a/doc/docs/C++_Tutorial.md b/doc/docs/C++_Tutorial.md
index 97b1dfd09..95c389195 100644
--- a/doc/docs/C++_Tutorial.md
+++ b/doc/docs/C++_Tutorial.md
@@ -190,7 +190,7 @@ while (f.time() < curr_time + 1/w_midgap) {
After we convert the HDF5 files to PNG format and superimpose the images on the dielectric background to produce an animated, we obtain the following:
-
+
Compiling
diff --git a/doc/docs/Exploiting_Symmetry.md b/doc/docs/Exploiting_Symmetry.md
index 972b4d9af..e760176da 100644
--- a/doc/docs/Exploiting_Symmetry.md
+++ b/doc/docs/Exploiting_Symmetry.md
@@ -26,7 +26,7 @@ Meep supports exploiting several kinds of symmetries:
- 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.
diff --git a/doc/docs/FAQ.md b/doc/docs/FAQ.md
index 6a16e866e..428ff426e 100644
--- a/doc/docs/FAQ.md
+++ b/doc/docs/FAQ.md
@@ -84,7 +84,7 @@ polarization is also zero. This is demonstrated in the figure below showing a
In the [interface](Python_User_Interface.md#source), the source currents are labeled $E_x$ or $H_y$ etc. according to what components of the electric/magnetic fields they correspond to.
-
+
### How do I compute the local density of states (LDOS) in a lossy material?
@@ -151,7 +151,7 @@ For an example of the second approach, see [Tutorial/Eigenmode Source/Planewaves
A focused beam with a Gaussian envelope can be created using the [`GaussianBeamSource`](Python_User_Interface.md#gaussianbeamsource) as demonstrated in this [script](https://github.com/NanoComp/meep/blob/master/python/examples/gaussian-beam.py). The following are four snapshots of the resulting field profile generated using a line source (red line) in 2d for different values of the beam waist radius/width $w_0$ (`beam_w0`), propagation direction $\vec{k}$ (`beam_kdir`), and focus (`beam_x0`):
-
+
Note: beams in a homogeneous material do *not* have a fixed width in Maxwell's equations; they always spread out during propagation (i.e., diffraction). The [numerical aperture (NA)](https://en.wikipedia.org/wiki/Gaussian_beam#Beam_divergence) of a Gaussian beam with waist radius $w$ and vacuum wavelength $\lambda$ within a medium of index $n$ is $n\sin(\lambda/(\pi nw))$.
@@ -165,7 +165,7 @@ A circularly polarized planewave in [cylindrical coordinates](Python_Tutorials/C
You can use an instantaneous [`ContinuousSource`](Python_User_Interface.md#continuoussource) with large wavelength (or nearly-zero frequency). This is analogous to a [direct current](https://en.wikipedia.org/wiki/Direct_current). You will also need to create a [run function](Python_User_Interface.md#run-functions) which contains [`change_sources`](Python_User_Interface.md#reloading-parameters) and specify the `center` property of the point source to be time dependent. As an example, the following image demonstrates [Cherenkov radiation](https://en.wikipedia.org/wiki/Cherenkov_radiation) involving a moving point charge with [superluminal phase velocity](https://en.wikipedia.org/wiki/Faster-than-light#Phase_velocities_above_c) (see [examples/cherenkov-radiation.py](https://github.com/NanoComp/meep/blob/master/python/examples/cherenkov-radiation.py)).
-
+
### Why doesn't the continuous-wave (CW) source produce an exact single-frequency response?
@@ -175,7 +175,7 @@ The [ContinuousSource](Python_User_Interface.md#continuoussource) does not produ
If the `width` is 0 (the default) then the source turns on sharply which creates high-frequency transient effects. Otherwise, the source turns on with a shape of (1 + tanh(t/`width` - `slowness`))/2. That is, the `width` parameter controls the width of the turn-on. The `slowness` parameter controls how far into the exponential tail of the tanh function the source turns on. The default `slowness` of 3.0 means that the source turns on at $(1 + \tanh(-3))/2 = 0.00247$ of its maximum amplitude. A larger value for `slowness` means that the source turns on even more gradually at the beginning (i.e., farther in the exponential tail). The effect of varying the two parameters `width` and `slowness` independently in the turn-on function is shown below.
-
+
Note: even if you have a continuous wave (CW) source at a frequency $\omega$, the time dependence of the electric field after transients have died away won't necessarily be $cos(\omega t)$, because in general there is a phase difference between the current and the resulting fields. In general for a CW source you will eventually get fields proportional to $cos(\omega t-\phi)$ for some phase $\phi$ which depends on the field component, the source position, and the surrounding geometry.
@@ -193,7 +193,7 @@ No. A narrow-bandwidth Gaussian is still a Gaussian: it goes to zero at both the
You can use a [`CustomSource`](Python_User_Interface.md#customsource) to define an arbitrary time-profile for the [`Source`](Python_User_Interface.md#source) object. As an example, the following snapshots of the out-of-plane electric field demonstrates a [linear-chirped pulse](https://www.rp-photonics.com/chirp.html) planewave propagating from the left to the right with higher frequencies (smaller wavelengths) at the front (i.e., a down chirp). For the simulation script, see [examples/chirped_pulse.py](https://github.com/NanoComp/meep/blob/master/python/examples/chirped_pulse.py).
-
+
Usage: Fields
@@ -252,7 +252,7 @@ For a linear system, you can use a [ContinuousSource](Python_User_Interface.md#c
The decay coefficient of the fields within any PML contains a $\cos(\theta)$ factor where $\theta$ is the incidence angle ($\theta=0^{\circ}$ is normal incidence). The decay therefore becomes *slower* as glancing incidence ($\theta=90^{\circ}$) is approached. This is true in the continuum limit and can be demonstrated by verifying that the reflections from the PML do *not* change with resolution. Otherwise, if the reflection decreases with increasing resolution then it may be due to transition reflections (i.e., the impedance mismatch at the PML interface) which can also be reduced by making the PML thicker instead of increasing the resolution. Transition reflections also increase as glancing incidence is approached, because at glancing incidence the phase-velocity mismatch between incident and reflected waves goes to zero as described in [Optics Express, Vol. 16, pp. 11376-92 (2008)](http://www.opticsinfobase.org/abstract.cfm?URI=oe-16-15-11376). Glancing-angle fields commonly arise in simulations where one direction is periodic and the other is terminated by a PML (such as in [diffraction gratings](Python_Tutorials/Mode_Decomposition.md#diffraction-spectrum-of-a-binary-grating)), in which case you can have spurious solutions that travel *parallel* to the PML interface; a workaround is to use a thicker non-PML [absorber](Python_User_Interface.md#absorber). This is demonstrated in the figure below by the glancing-angle fields remaining in the cell after a [source planewave](Python_Tutorials/Eigenmode_Source.md#planewaves-in-homogeneous-media) at 45° has long been turned off: the PML (left inset) is unable to absorb these fields unlike the absorber (right inset).
-
+
### How do I compute the modes of a non-orthogonal (i.e., triangular) lattice?
@@ -352,7 +352,7 @@ Still, there are times when, for whatever reason, you might not want this featur
Even if you disable the subpixel averaging, however, when you output the dielectric function to a file and visualize it, you may notice that there are some pixels with intermediate ε values, right at the boundary between two materials. This is due to a completely different reason. Internally, Meep's simulation is performed on a [Yee grid](Yee_Lattice.md), in which every field component is stored on a slightly different grid which are offset from one another by half-pixels, and the ε values are also stored on this Yee grid. For output purposes, however, it is more user-friendly to output all fields etcetera on the same grid at the center of each pixel, so all quantities are interpolated onto this grid for output. Therefore, even though the internal $\varepsilon$ values are indeed discontinuous when you disable subpixel averaging, the output file will still contain some "averaged" values at interfaces due to the interpolation from the Yee grid to the center-pixel grid. For the same reason, if `k_point` is set and the boundaries are Bloch-periodic, the permittivity function of the entire cell obtained via `get_epsilon` or `output_epsilon` will show that a little of the cell from one edge "leaks" over to the other edge: these extra pixels are added to implement the boundary conditions. This is independent of PML and the way the structure is defined (i.e., using geometric objects or a material function, etc.). An example is shown in the figure below comparing `output_epsilon` for two cases involving with and without `k_point`. The discretization artifacts are highlighted.
-
+
### Why does subpixel averaging take so long?
diff --git a/doc/docs/Introduction.md b/doc/docs/Introduction.md
index 1ea0901db..fb6214985 100644
--- a/doc/docs/Introduction.md
+++ b/doc/docs/Introduction.md
@@ -17,13 +17,13 @@ Meep simulates [Maxwell's equations](https://en.wikipedia.org/wiki/Maxwell's_equ
-$\frac{d\mathbf{B}}{dt} = -\nabla\times\mathbf{E} - \mathbf{J}_B - \sigma_B \mathbf{B}$
+$$\frac{d\mathbf{B}}{dt} = -\nabla\times\mathbf{E} - \mathbf{J}_B - \sigma_B \mathbf{B}$$
-$\mathbf{B} = \mu \mathbf{H}$
+$$\mathbf{B} = \mu \mathbf{H}$$
-$\frac{d\mathbf{D}}{dt} = \nabla\times\mathbf{H} - \mathbf{J} - \sigma_D \mathbf{D}$
+$$\frac{d\mathbf{D}}{dt} = \nabla\times\mathbf{H} - \mathbf{J} - \sigma_D \mathbf{D}$$
-$\mathbf{D} = \varepsilon \mathbf{E}$
+$$\mathbf{D} = \varepsilon \mathbf{E}$$
@@ -31,9 +31,9 @@ where $\mathbf{D}$ is the displacement field, $\varepsilon$ is the dielectric co
-$\nabla \cdot \mathbf{B} = - \int^t \nabla \cdot (\mathbf{J}_B(t') + \sigma_B \mathbf{B}) dt'$
+$$\nabla \cdot \mathbf{B} = - \int^t \nabla \cdot (\mathbf{J}_B(t') + \sigma_B \mathbf{B}) dt'$$
-$\nabla \cdot \mathbf{D} = - \int^t \nabla \cdot (\mathbf{J}(t') + \sigma_D \mathbf{D})dt' \equiv \rho$
+$$\nabla \cdot \mathbf{D} = - \int^t \nabla \cdot (\mathbf{J}(t') + \sigma_D \mathbf{D})dt' \equiv \rho$$
diff --git a/doc/docs/Materials.md b/doc/docs/Materials.md
index 3092a3a60..b176a842d 100644
--- a/doc/docs/Materials.md
+++ b/doc/docs/Materials.md
@@ -172,10 +172,10 @@ Analytically, what this means is that the resonances that are present in the sys
Although Meep is using an oscillator model equation for the atomic polarization and level populations, instead of the Bloch equations, Meep retains the two terms usually approximated to zero when deriving the oscillator model equations from the Bloch equations, and so these equations are exactly equivalent to the Bloch equations. For more details, see [arXiv:2007.09329](https://arxiv.org/abs/2007.09329) and Section 6.4.1 of [Nonlinear Optics (third edition)](https://www.amazon.com/Nonlinear-Optics-Third-Robert-Boyd/dp/0123694701) by R. W. Boyd. To verify this equivalence between the different equations for modeling the polarization, as well as confirm that saturable media have been properly implemented in Meep, we compare the results of Meep with an independent FDTD solver using the Bloch equations and the frequency domain steady-state ab initio laser theory (SALT), in a 1d, one-sided, Fabry-Perot cavity containing a two-level gain medium that exhibits steady-state, multi-mode lasing. The cavity has a length of $a = 1$, a background index of $n = 1.5$, an atomic transition frequency of $\omega_n = 40/(2\pi)$, with width $\gamma_n = 8/(2\pi)$, the decay rate from level $2$ to $1$ is $\Gamma_{21} = 0.005$, the pumping rate from $1$ to $2$ is $\Gamma_{12} = 0.0051$, and the total atomic density, $N_0$, of the system was varied to produce different amounts of gain. These plots are given in terms of the equilibrium inversion, $D_0$, which is the inversion of the saturable gain medium in the absence of an electric field, i.e. the value of $\Delta N$ when $\mathbf{E} = 0$. There is agreement among the three methods close to the initial as well as past the third lasing threshold as shown in the following two figures.
-
+
-
+
For the two-level atomic gain model used in this example, $D_0$ can be calculated as:
@@ -313,7 +313,7 @@ plt.show()
```
-
+
**Note:** for narrowband calculations, some of the Lorentzian susceptibility terms may be unnecessary and will contribute to consuming more computational resources than are required (due to the additional storage and time stepping of the polarization fields). Computational efficiency can be improved (without significantly affecting accuracy) by removing from the material definitions those Lorentzian susceptibility terms which are far outside the spectral region of interest. In addition, when using the materials library the Courant parameter may need to be reduced to achieve meaningful results, see [Numerical Stability](Materials.md#numerical-stability).
diff --git a/doc/docs/Parallel_Meep.md b/doc/docs/Parallel_Meep.md
index 4f29cc9d9..044518b8e 100644
--- a/doc/docs/Parallel_Meep.md
+++ b/doc/docs/Parallel_Meep.md
@@ -70,7 +70,7 @@ An alternative to having Meep automatically partition the cell at runtime into c
As a demonstration, an example of a 2d cell partition along with its binary-tree representation is shown below. The 10×5 cell in $xy$ coordinates with origin at the cell center is partitioned into five chunks numbered one through five.
-
+
This binary tree can be described as a list of lists where each list entry is `[ (split_dir,split_pos), left, right ]` for which `split_dir` and `split_pos` define the splitting direction and position, and `left` and `right` are the left and right branches which can be either another list defining a new node or a process ID. Based on these specifications, the cell partition from above can be set up as follows:
@@ -143,11 +143,11 @@ The following are benchmarking results of the total runtime vs. number of proces
As shown in the first figure below, the runtime reaches a minimum at 77 processors. The second figure shows the scaling of the ratio of the mean time spent on communication (MPI/synchronization) to the computation (time stepping and DFTs). (Timing metrics were obtained using [`Simulation.mean_time_spent_on`](Python_User_Interface.md#simulation-time).) This ratio is a measure of the parallelization efficiency. The crossover point when the parallelization efficiency becomes larger than one — the regime in which the simulation is constrained by the network bandwidth rather than the CPU clock speed — corresponds well to the minimum runtime of the first figure.
-
+
-
+
These results are not continuous because as the number of processors changes slightly (e.g., from 42 to 49), the chunk divisions can change by a lot (i.e., it can switch from splitting some chunk along the $x$ axis to along the $y$ axis) which significantly affects the runtime performance. Also, in general, benchmarking studies involving MPI jobs are challenging because there are [a number of factors which can affect the results](https://www.open-mpi.org/faq/?category=tuning#running-perf-numbers).
@@ -155,7 +155,7 @@ These results are not continuous because as the number of processors changes sli
For a given cluster, we can also analyze the time spent by each processor on time-stepping, MPI/synchronization, and DFT. This is shown in the next figure for the case of a cluster with 35 processors (5 nodes). Because the simulation is not properly load balanced due to the equal-sized chunks, there is a large variation in the timings for different processors particularly for the DFT where there are several idle processors (i.e., chunks which do not contain any DFT pixels).
-
+
Based on these results, we plot the average of the *inverse* of the timings (proportional to the number of cycles per second; a "rate" quantity which can demonstrate linear scaling) for the time-stepping and DFT over the full range of cluster sizes. The time-stepping results demonstrate (approximately) linear scaling. The size of the error bars increases with the number of cluster nodes mainly due to pronounced variations in the network bandwidth; the N1 instances do *not* support colocation via a [compact placement policy](https://cloud.google.com/solutions/best-practices-for-using-mpi-on-compute-engine). The DFT results (which excludes those processors without any DFT pixels) seem to be oscillating around a constant. This is not surprising because the processor(s) which takes the longest time to update its DFT pixels sets an upper bound on how fast the DFT calculation for all processors can proceed. It is the presence of this unique upper bound for each cluster which is revealed by the scaling plot.
@@ -163,11 +163,11 @@ Based on these results, we plot the average of the *inverse* of the timings (pro
See also [FAQ/Should I expect linear speedup from the parallel Meep](FAQ.md#should-i-expect-linear-speedup-from-the-parallel-meep)?
-
+
-
+
@@ -177,7 +177,7 @@ Dynamic Chunk Balancing
Since Meep's computation time is ultimately bottlenecked by the slowest-running process, it is desirable to load-balance the chunk layout such that each compute node is given an equal workload. By default, Meep uses a heuristics-based scheme to estimate the cost of a computation region based on the composition of voxel types (anisotropic, PML, etc.) However, this method of estimating the simulation time for a chunk in advance is not always accurate, a problem which is especially true for simulations run on shared-resource clusters. Meep's `chunk_balancer` module allows for a more empirical, data-driven approach for dynamically load-balancing parallel simulations. This approach uses the simulation time per node to adaptively modify the chunk layout and it implicitly corrects for heterogeneity over the simulation region and variability in background loads and job priority on shared compute resources. This approach can be especially useful for cases such as adjoint optimization, where slight variations on the same simulation are run many times over many iterations.
-
+
### Chunk balancer interface
@@ -298,10 +298,10 @@ def adjust_split_pos(node):
The following benchmarking results show load-balancing improvements from a parallel run on a shared compute cluster in a datacenter. The per-core working times (blue and orange) start of initially poorly balanced using the default `split_by_cost` scheme, but the load balancing improves over successive iterations.
-
+
Using the normalized standard deviation in simulation times per iteration as a proxy for load-balancing efficacy, we can see that the load balance improves over a large number of runs with varying numbers of processes:
-
+
diff --git a/doc/docs/Perfectly_Matched_Layer.md b/doc/docs/Perfectly_Matched_Layer.md
index 1c6e49b5a..7578ee0ff 100644
--- a/doc/docs/Perfectly_Matched_Layer.md
+++ b/doc/docs/Perfectly_Matched_Layer.md
@@ -19,7 +19,7 @@ Breakdown of PML in Inhomogeneous Media
As shown in the figure below, there are two important cases involving *inhomogeneous* media where the fundamental coordinate stretching idea behind PML breaks down giving rise to reflection artifacts. The workaround is to replace the PML with an adiabatic [absorber](Python_User_Interface.md#absorber). Additionally, if you operate near a low-group velocity band edge in a periodic media, you may need to make the PML/absorber very thick (overlapping many periods) to be effective. For more details on why PML breaks down in these cases, see [Optics Express, Vol. 16, pp. 11376-92 (2008)](http://www.opticsinfobase.org/abstract.cfm?URI=oe-16-15-11376). Also, [Physical Review E, Vol. 79, 065601 (2011)](http://math.mit.edu/~stevenj/papers/LohOs09.pdf) describes a separate case where PML fails involving backward-wave modes which may occur at metal-dielectric interfaces (i.e., [surface-plasmon polaritons](https://en.wikipedia.org/wiki/Surface_plasmon_polariton)).
-
+
Planewave Sources Extending into PML
@@ -54,13 +54,13 @@ plt.show()
```
-
+
For an $E_y$-polarized source and `is_integrated=True`, the wavefronts are planar only in the non-PML region as shown below. This is because the $E_y$ fields in the $y$-PML are being rescaled by a Jacobian matrix. (The key thing to remember is that the fields in the PML region are not "physical," but are carefully designed artificial quantities in order to eliminate boundary reflections; you should generally extract physical data only from the interior of the computational cell (outside the PML).)
-
+
In the future, `is_integrated=True` will be set automatically for sources extending into the PML ([#1049](https://github.com/NanoComp/meep/issues/1049)).
diff --git a/doc/docs/Python_Developer_Information.md b/doc/docs/Python_Developer_Information.md
index 13d930949..ff4e96bc0 100644
--- a/doc/docs/Python_Developer_Information.md
+++ b/doc/docs/Python_Developer_Information.md
@@ -5,11 +5,11 @@
The `meep` Python package consists of a low-level interface and a high-level interface. The low-level interface is the direct result of running [SWIG](http://www.swig.org/) on the C++ headers.
-
+
Next, we compile `meep-python.cxx`, rename `meep.py` to `__init__.py` and put them in a folder called `meep`. Putting all the code in `__init__.py` allows us to access the symbols directly from the `meep` namespace rather than going through an additional module like `meep.meep.vec`. Now we have a complete Python package.
-
+
`__init__.py` contains "proxy" classes for all public `meep` objects. They hold a `this` pointer that dispatches to the appropriate C++ functions in the `_meep.so` extension module. The interface this package exposes is basically the same as the C++ interface. That is, a simulation written in this low-level Python interface would not look much different from the same simulation written in C++. By implementing a high-level interface on top of the basic SWIG wrappers, we can abstract away many of the low details of setting up a simulation, take advantage of Python language features like keyword arguments, and gain productivity from libraries like NumPy.
diff --git a/doc/docs/Python_Tutorials/Basics.md b/doc/docs/Python_Tutorials/Basics.md
index 67057e4c8..0b6df296b 100644
--- a/doc/docs/Python_Tutorials/Basics.md
+++ b/doc/docs/Python_Tutorials/Basics.md
@@ -52,7 +52,7 @@ geometry = [mp.Block(mp.Vector3(mp.inf,1,mp.inf),
The waveguide is specified by a `Block` (parallelepiped) of size $\infty \times 1 \times \infty$, with $ε=12$, centered at (0,0) which is the center of the cell. By default, any place where there are no objects there is air ($ε=1$), although this can be changed by setting the `default_material` variable. The resulting structure is shown below.
-
+
We have the structure and need to specify the current sources using the `sources` object. The simplest thing is to add a single point source $J_z$:
@@ -123,7 +123,7 @@ plt.axis('off')
plt.show()
```
-
+
We see that the the source has excited the waveguide mode but has also excited radiating fields propagating away from the waveguide. At the boundaries, the field quickly goes to zero due to the PML.
@@ -153,7 +153,7 @@ resolution = 10
Note that we have *two* blocks, both off-center to produce the bent waveguide structure pictured below. As illustrated in the figure, the origin (0,0) of the coordinate system is at the center of the cell, with positive $y$ being downwards, and thus the block of size 12$\times$1 is centered at (-2,-3.5). Also shown in green is the source plane at $x=-7$ which is shifted to $y=-3.5$ so that it is still inside the waveguide.
-
+
There are a couple of items to note. First, a point source does not couple very efficiently to the waveguide mode, so we'll expand this into a line source, centered at (-7,-3.5), with the same width as the waveguide by adding a `size` property to the source. This is shown in green in the figure above. An [eigenmode source](../Python_User_Interface.md#eigenmodesource) can also be used which is described in [Tutorial/Optical Forces](Optical_Forces.md). Second, instead of turning the source on suddenly at $t=0$ which excites many other frequencies because of the discontinuity, we will ramp it on slowly. Meep uses a hyperbolic tangent (tanh) turn-on function over a time proportional to the `width` of 20 time units which is a little over three periods. Finally, just for variety, we'll specify the vacuum wavelength instead of the frequency; again, we'll use a wavelength such that the waveguide is half a wavelength wide.
@@ -203,13 +203,13 @@ unix% convert ez.t*.png ez.gif
We are using an animated GIF format for the output. This results in the following animation:
-
+
It is clear that the transmission around the bend is rather low for this frequency and structure — both large reflection and large radiation loss are clearly visible. Moreover, since we are operating just barely below the cutoff for single-mode behavior, we are able to excite a second *leaky* mode after the waveguide bend, whose second-order mode pattern (superimposed with the fundamental mode) is apparent in the animation. Below, we show a field snapshot from a simulation with a larger cell along the $y$ direction, in which you can see that the second-order leaky mode decays away, leaving us with the fundamental mode propagating downward.
-
+
Instead of doing an animation, another interesting possibility is to make an image from a $x \times t$ slice. To get the $y=-3.5$ slice, which gives us an image of the fields in the first waveguide branch as a function of time, we can use `get_array` in a step function to collect a slice for each time step:
@@ -232,7 +232,7 @@ plt.axis('off')
plt.show()
```
-
+
#### Output Tips and Tricks
@@ -423,7 +423,7 @@ if mp.am_master():
plt.show()
```
-
+
We should also check whether our data is converged. We can do this by increasing the resolution and cell size and seeing by how much the numbers change. In this case, we'll try doubling the cell size:
@@ -627,7 +627,7 @@ cbar.set_ticklabels(["{:.1f}".format(t) for t in np.arange(0,0.4,0.1)])
plt.show()
```
-
+
Mie Scattering of a Lossless Dielectric Sphere
@@ -640,7 +640,7 @@ The scattering cross section ($\sigma_{scat}$) is the scattered power in all dir
A schematic of the 2d cross section at $z=0$ of the 3d cell is shown below.
-
+
The simulation script is in [examples/mie_scattering.py](https://github.com/NanoComp/meep/blob/master/python/examples/mie_scattering.py). The notebook is [examples/mie_scattering.ipynb](https://nbviewer.jupyter.org/github/NanoComp/meep/blob/master/python/examples/mie_scattering.ipynb). As an estimate of runtime, the [parallel simulation](../Parallel_Meep.md) on a machine with three Intel Xeon 4.20 GHz cores takes less than five minutes.
@@ -770,7 +770,7 @@ The incident intensity (`intensity`) is the flux in one of the six monitor plane
Results are shown below. Overall, the Meep results agree well with the analytic theory.
-
+
Finally, for the case of a *lossy* dielectric material (i.e. complex refractive index) with non-zero absorption, the procedure to obtain the scattering efficiency is the same. The absorption efficiency is the ratio of the absorption cross section ($\sigma_{abs}$) to the cross sectional area of the sphere. The absorption cross section is the total absorbed power divided by the incident intensity. The absorbed power is simply flux into the same box as for the scattered power, but *without* subtracting the incident field (and with the opposite sign, since absorption is flux *into* the box and scattering is flux *out of* the box): omit the `load_minus_flux_data` calls. The extinction cross section ($\sigma_{ext}$) is simply the sum of the scattering and absorption cross sections: $\sigma_{scat}+\sigma_{abs}$.
@@ -1018,14 +1018,14 @@ There is one important item to note: in order to eliminate discretization artifa
A schematic of the simulation layout generated using [`plot2D`](../Python_User_Interface.md#data-visualization) shows the line source (red), PMLs (green hatch region), `dft_flux` box (solid blue contour line), and `dft_fields` surface (blue hatch region).
-
+
The spatial map of the absorbed power density shows that most of the absorption occurs in a small region near the back surface of the cylinder (i.e., on the opposite side of the incident planewave).
-
+
@@ -1131,9 +1131,9 @@ unix% convert ring-ez-*.png ring-ez-0.118.gif
The resulting animations for (from left to right) 0.118, 0.147, and 0.175, are below, in which you can clearly see the radiating fields that produce the losses:
-
-
-
+
+
+
diff --git a/doc/docs/Python_Tutorials/Custom_Source.md b/doc/docs/Python_Tutorials/Custom_Source.md
index 47e49797a..f63288db4 100644
--- a/doc/docs/Python_Tutorials/Custom_Source.md
+++ b/doc/docs/Python_Tutorials/Custom_Source.md
@@ -14,7 +14,7 @@ In addition to the two source time profiles of a [continuous wave](../Python_Use
This tutorial example involves computing the radiated [flux](../Introduction.md#transmittancereflectance-spectra) from $N=10$ dipole emitters of a 2d LED-like periodic structure with a thin (1d) light-emitting layer. A schematic of the unit cell geometry and simulation layout is shown below. A silver (Ag) back reflector is used to direct nearly all the flux upwards into the $+y$ direction. PML is used to terminate the air region at the top of the cell. (Note: PML is not necessary at the bottom of the cell due to the Ag layer which is effectively a lossless mirror with [skin depth](https://en.wikipedia.org/wiki/Skin_effect) of a few nanometers at a wavelength of 1 μm.) The emitting layer is placed within a lossless dielectric substrate with wavelength-independent refractive index of 3.45.
-
+
One can take two different approaches to computing the radiated flux based on the type of emitter: (1) random or (2) deterministic. In Method 1 (brute-force Monte Carlo), each emitter is a white-noise dipole: every timestep for every dipole is an independent random number. A single run involves all $N$ dipoles which are modeled using a `CustomSource`. The stochastic results for the radiated flux are averaged over multiple trials/iterations via [Monte Carlo sampling](https://en.wikipedia.org/wiki/Monte_Carlo_method). Method 2 exploits the property of [linear time-invariance](https://en.wikipedia.org/wiki/Linear_time-invariant_system) of the materials/geometry and involves a sequence of $N$ separate runs each with a single deterministic dipole (i.e., pulse time profile, `GaussianSource`) at different positions in the emitting layer. Because dipoles at different positions are uncorrelated, the radiated flux from the ensemble is simply the average of all the individual iterations. (The interference terms between different dipoles integrate to zero when averaging over all possible phases.) The two approaches converge towards identical results, but Method 1 is more computationally expensive than Method 2 due to the much larger number of trials/iterations ($\gg N$) required to attain low noise variance. (Even more sophisticated deterministic methods exist to reduce the number of separate simulations, especially at high resolutions; for example, replacing the point-dipole sources with a [rapidly converging set of smooth basis functions](https://journals.aps.org/pra/abstract/10.1103/PhysRevA.81.012119) as demonstrated below, or fancier methods that exploit [trace-estimation methods](https://arxiv.org/abs/2111.13046) and/or transform volumetric sources to [surface sources](http://doi.org/10.1103/PhysRevB.88.054305).)
@@ -173,13 +173,13 @@ plt.show()
Results for Method 1 for three different numbers of trials/iterations (10, 50, and 500) are shown in the following three figures. Each trial/iteration involves two runs: one each for the flat and textured surface. As the number of trials/iterations is increased, the "noisiness" in the plot is gradually reduced. However, the total runtime increases significantly.
-
+
The next figure shows a comparison of the normalized radiated flux for Method 1 (500 trials) and 2 (20 runs; 10 runs each for the flat and textured surface). The results show good agreement over the entire bandwidth spectrum. The Method 1 results (labeled "Monte Carlo") required almost *four days* of compute time using an Intel Xeon processor with two single-threaded cores at 3.8 GHz whereas the Method 2 results (labeled "Deterministic") were obtained in 24 minutes. In general, deterministic approaches tend to be more efficient than brute-force Monte Carlo.
-
+
One situation in which you may need to perform brute-force Monte Carlo simulations is that of nonlinear or time-varying media, because the equivalence between random and deterministic simulations above relied on linearity and time-invariance. However, in such media one also cannot directly employ white-noise sources, but you must instead input the noise with the correct spectrum for your desired emission process. For example, to [model thermal emission in a nonlinear medium](http://doi.org/10.1103/PhysRevB.91.115406) one must have a noise spectrum consistent with the [fluctuation-dissipation theorem](https://en.wikipedia.org/wiki/Fluctuation-dissipation_theorem), which can be achieved using the `NoisyLorentzianSusceptibility` feature in Meep.
@@ -309,7 +309,7 @@ There are three items to note in this script. (1) The line source spans the enti
Method 3 requires a convergence check in which $M$ (`nsrc` in the script) is repeatedly doubled until the change in the results are within a desired tolerance of e.g., < 1%. For this example, $M=15$ was found to be sufficient. Note that because a line source with a cosine amplitude function in *homogeneous* media is analogous to generating a planewave at a discrete angle, at each frequency $\omega$ there exists a cutoff $M$ beyond which there are *no* propagating planewaves. The cutoff $M$ can be computed analytically using the grating equation: $\sqrt{\omega^2n^2 - \left(k_x+\frac{M\pi}{L}\right)^2} = 0$, where $n$ is the refractive index of the source medium and $k_x$ is the Bloch-periodic wavevector in the $x$ direction. In this example, $\omega=2\pi$ (pulse center frequency), $L=1.5$, $k_x=0$, and $n=3.45$ for which the largest propagating $M$ is 10. For $M > 10$ the cosine source produces evanescent *waves in the material*, but these waves scatter into other Fourier components (including propagating waves) once they hit the grating. Thus, the source still produces propagating waves, but the amplitude of the propagating waves (and hence the contribution to the power) decreases exponentially for $M > 10$ as the coupling between the source and the grating decreases. This effect is demonstrated in the figure below which is a semilog plot of the $L_2$ norm of the error in the normalized flux of the cosine source relative to the "correct" result computed using 75 point dipoles (Method 2) as a function of the number of terms in the cosine source. The error decreases exponentially for $M > 10$ until $M=12$, at which point it becomes limited by discretization error (both the point-dipole and cosine-source methods have discretization errors at finite resolution, but are discretized slightly differently); as resolution is increased, this minimum difference will go to zero. Note that this analysis is only applicable to periodic structures where the line source extends the entire width of the cell with periodic boundary conditions. A finite length source in a non-periodic cell has no such cutoff and thus will typically require a large number of cosine terms for convergence.
-
+
@@ -360,7 +360,7 @@ plt.show()
Results for Method 2 and 3 are shown in the following figure. The agreement is good but there is a significant difference in the runtime. Method 2 (labeled "Point Source") involves $N=75$ simulations each for the flat and textured surface for a total of 150 runs which required 10.6 hours. Method 3 (labeled "Line Source") involves $M=15$ simulations for the flat/textured surface for a total of 30 runs which required just 2.0 hours.
-
+
diff --git a/doc/docs/Python_Tutorials/Cylindrical_Coordinates.md b/doc/docs/Python_Tutorials/Cylindrical_Coordinates.md
index 25b16b25d..b3afbd60b 100644
--- a/doc/docs/Python_Tutorials/Cylindrical_Coordinates.md
+++ b/doc/docs/Python_Tutorials/Cylindrical_Coordinates.md
@@ -145,17 +145,17 @@ Note that, because of the `to_appended` command, the `ring-cyl-ez.h5` file is a
$E_z$ for $\omega$=0.118 $m$=3 mode:
-
+
$E_z$ for $\omega$=0.148 $m$=4 mode:
-
+
$E_z$ for $\omega$=0.176 $m$=5 mode:
-
+
Because only the $\phi$=0 slice is used, the visual distinction between $m$ values is much less than with the 2d simulation. What is apparent is that, as the frequency increases, the mode becomes more localized in the waveguide and the radiating field (seen in the $r \times t$ slice as curved waves extending outward) becomes less, as expected.
@@ -452,7 +452,7 @@ Note that the "closed" DFT flux box is comprised of just three flux objects: two
As shown below, the results for the scattering cross section computed using cylindrical coordinates agree well with the 3d Cartesian simulation. However, there is a large discrepancy in performance: for a single Intel Xeon 4.2GHz processor, the runtime of the cylindrical simulation is nearly 90 times shorter than the 3d simulation.
-
+
@@ -468,7 +468,7 @@ $$ r_n^2 = n\lambda (f+\frac{n\lambda}{4})$$
where $n$ is the zone index (1,2,3,...,$N$), $f$ is the focal length, and $\lambda$ is the operating wavelength. The main design variable is the number of zones $N$. The design specifications of the zone plate are similar to the binary-phase grating in [Tutorial/Mode Decomposition/Diffraction Spectrum of a Binary Grating](Mode_Decomposition.md#diffraction-spectrum-of-a-binary-grating) with refractive index of 1.5 (glass), $\lambda$ of 0.5 μm, and height of 0.5 μm. The focusing property of the zone plate is verified by the concentration of the electric-field energy density at the focal length of 0.2 mm (which lies *outside* the cell). The planewave is incident from within a glass substrate and spans the entire length of the cell in the radial direction. The cell is surrounded on all sides by PML. A schematic of the simulation geometry for a design with 25 zones and flat-surface termination is shown below. The near-field monitor is positioned at the edge of the PML and captures the scattered fields in *all* directions.
-
+
The simulation script is in [examples/zone_plate.py](https://github.com/NanoComp/meep/blob/master/python/examples/zone_plate.py). The notebook is [examples/zone_plate.ipynb](https://nbviewer.jupyter.org/github/NanoComp/meep/blob/master/python/examples/zone_plate.ipynb).
@@ -584,4 +584,4 @@ Note that the volume specified in `get_farfields` via `center` and `size` is in
Shown below is the far-field energy-density profile around the focal length for both the *r* and *z* coordinate directions for three lens designs with $N$ of 25, 50, and 100. The focus becomes sharper with increasing $N$ due to the enhanced constructive interference of the diffracted beam. As the number of zones $N$ increases, the size of the focal spot (full width at half maximum) at $z = 200$ μm decreases as $1/\sqrt{N}$ (see eq. 17 of the [reference](http://zoneplate.lbl.gov/theory)). This means that doubling the resolution (halving the spot width) requires quadrupling the number of zones.
-
+
diff --git a/doc/docs/Python_Tutorials/Eigenmode_Source.md b/doc/docs/Python_Tutorials/Eigenmode_Source.md
index b4bebf0d7..b31e2ae7d 100644
--- a/doc/docs/Python_Tutorials/Eigenmode_Source.md
+++ b/doc/docs/Python_Tutorials/Eigenmode_Source.md
@@ -12,7 +12,7 @@ Index-Guided Modes in a Ridge Waveguide
The first structure, shown in the schematic below, is a 2d ridge waveguide with ε=12, width $a$=1 μm, and out-of-plane electric field Ez. The dispersion relation ω(k) for index-guided modes with *even* mirror symmetry in the $y$-direction is computed using [MPB](https://mpb.readthedocs.io/en/latest/) and shown as blue lines. The light cone which denotes radiative modes is the section in solid green. Using this waveguide configuration, we will investigate two different frequency regimes: (1) single mode (normalized frequency of 0.15) and (2) multi mode (normalized frequency of 0.35), both shown as dotted horizontal lines in the figures. We will use the eigenmode source to excite a specific mode in each case — labeled **A** and **B** in the band diagram — and compare the results to using a constant-amplitude source for straight and rotated waveguides. Finally, we will demonstrate that a single monitor plane in the $y$-direction is sufficient for computing the total Poynting flux in a waveguide with any arbitrary orientation.
-
+
The simulation script is in [examples/oblique-source.py](https://github.com/NanoComp/meep/blob/master/python/examples/oblique-source.py). The notebook is [examples/oblique-source.ipynb](https://nbviewer.jupyter.org/github/NanoComp/meep/blob/master/python/examples/oblique-source.ipynb).
@@ -179,13 +179,13 @@ if mp.am_master():
Results are shown for the single mode waveguide with one eigenmode **A** (band 1) using a center frequency of `0.15` and multi mode waveguide with two eigenmodes **A** (higher-order mode, band 2) and **B** (fundamental mode, band 1), all with a center frequency of `0.35`.
-
+
-
+
-
+
@@ -200,14 +200,14 @@ The eigenmode source can also be used to launch modes in an oblique/rotated wave
Note that an oblique waveguide leads to a breakdown in the [PML](../Perfectly_Matched_Layer.md#breakdown-of-pml-in-inhomogeneous-media). A simple workaround for mitigating the PML reflection artifacts in this case is to double the `thickness` from 1 to 2.
-
+
There are numerical dispersion artifacts due to the FDTD spatial and temporal discretizations which create negligible backward-propagating waves by the eigenmode current source, carrying approximately 10-5 of the power of the desired forward-propagating mode. These artifacts can be seen as residues in the field profiles.
-
+
We can demonstrate that the total power in a waveguide with *arbitrary* orientation — computed using two equivalent methods via `get_fluxes` and [mode decomposition](../Mode_Decomposition.md) — can be computed by a single flux plane oriented along the $y$ direction: thanks to [Poynting's theorem](https://en.wikipedia.org/wiki/Poynting%27s_theorem), the flux through any plane crossing a lossless waveguide is the same, regardless of whether the plane is oriented perpendicular to the waveguide. Furthermore, the eigenmode source is normalized in such a way as to produce the same power regardless of the waveguide orientation — in consequence, the flux values for mode **A** of the single-mode case for rotation angles of 0°, 20°, and 40° are 1111.280794, 1109.565028, and 1108.759159, within 0.2% (discretization error) of one another. Note that the Poynting flux could have been normalized to unity by setting the `EigenModeSource`/`Source` object parameter `amplitude=1/src.fourier_transform(fsrc)` where `fsrc=0.15` and `src=mp.GaussianSource(fsrc,fwidth=0.2*fsrc)`.
@@ -215,14 +215,14 @@ We can demonstrate that the total power in a waveguide with *arbitrary* orientat
Finally, we demonstrate that as long as the line source intersects the waveguide *and* `eig_kpoint` is not nearly parallel to the direction of the line source, the mode can be properly launched. As shown in the field profiles below for the single-mode waveguide, there does not seem to be any noticeable distortion in the launched mode as the waveguide approaches glancing incidence to the source plane up to 80°, where the total power in the forward-propagating mode is 97%. Note that the line source spans the entire length of the cell extending into the PML region (not shown). In this example where the cell length is 10 μm (or 10X the width of the waveguide), the maximum rotation angle is ~84°, where the power drops to 59% and backward-propagating fields are clearly visible.
-
+
Increasing the size of the cell improves results at the expense of a larger simulation. The field profiles shown below are for a cell where the length has been doubled to 20 μm. The waveguide power at 84° increases from 59% to 80%. However, as the waveguide mode approaches glancing incidence, sensitivity to discretization errors increases because the mode varies rapidly with frequency on a glancing-angle cross-section, and you will eventually need to increase the resolution as well as the cell size. For waveguide angles much beyond 45° you probably want to simply change the orientation of the line source by 90°.
-
+
@@ -287,4 +287,4 @@ Note that the line source spans the *entire* length of the cell. (Planewave sour
Shown below are the steady-state field profiles generated by the planewave for the three rotation angles. Residues of the backward-propagating waves due to the discretization are slightly visible.
-
+
diff --git a/doc/docs/Python_Tutorials/Frequency_Domain_Solver.md b/doc/docs/Python_Tutorials/Frequency_Domain_Solver.md
index 440905d27..b0bdc0bf3 100644
--- a/doc/docs/Python_Tutorials/Frequency_Domain_Solver.md
+++ b/doc/docs/Python_Tutorials/Frequency_Domain_Solver.md
@@ -92,7 +92,7 @@ else:
The results are shown in the figure below. The error in the fields decreases monotonically with decreasing tolerance of the frequency-domain solver. The error is converging to an asymptotic limit of `1e-12` which is set by the lowest tolerance.
-
+
diff --git a/doc/docs/Python_Tutorials/GDSII_Import.md b/doc/docs/Python_Tutorials/GDSII_Import.md
index 12278678e..16843f553 100644
--- a/doc/docs/Python_Tutorials/GDSII_Import.md
+++ b/doc/docs/Python_Tutorials/GDSII_Import.md
@@ -12,7 +12,7 @@ S-Parameters of a Directional Coupler
The directional coupler as well as the source and mode monitor geometries are described by the GDSII file [`examples/coupler.gds`](https://github.com/NanoComp/meep/blob/master/python/examples/coupler.gds). A snapshot of this file viewed using [KLayout](https://www.klayout.de/) is shown below. The figure labels have been added in post processing. The design consists of two identical [strip waveguides](http://www.simpetus.com/projects.html#mpb_waveguide) which are positioned close together via an adiabatic taper such that their modes couple evanescently. There is a source (labelled "Source") and four mode monitors (labelled "Port 1", "Port 2", etc.). The input pulse from Port 1 is split in two and exits through Ports 3 and 4. The design objective is to find the separation distance which maximizes the outgoing power in Port 4 at a wavelength of 1.55 μm. More generally, though not included in this example, it is possible to have two additional degrees of freedom: (1) the length of the straight waveguide section where the two waveguides are coupled and (2) the length of the tapered section (the taper profile is described by a hyperbolic tangent (tanh) function).
-
+
@@ -145,7 +145,7 @@ if __name__ == '__main__':
For a given waveguide separation distance ($d$), the simulation computes the transmittance of Ports 2, 3, and 4. The transmittance is the square of the [S-parameter](https://en.wikipedia.org/wiki/Scattering_parameters) which itself is equivalent to the [mode coefficient](Mode_Decomposition.md). There is an additional mode monitor at Port 1 to compute the input power from the adjacent eigenmode source; this is used for normalization when computing the transmittance. The eight layers of the GDSII file are each converted to a `Simulation` object: the upper and lower branches of the coupler are defined as a collection of [`Prism`](../Python_User_Interface.md#prism)s, the rectilinear regions of the source and flux monitor as a [`Volume`](../Python_User_Interface.md#volume) and [`FluxRegion`](../Python_User_Interface.md#fluxregion). The size of the cell in the $y$ direction is dependent on $d$. The default dimensionality is 2d. (Note that for a 2d cell the `Prism` objects returned by `get_GDSII_prisms` must have a finite height. The finite height of `Volume` objects returned by `GDSII_vol` are ignored in 2d.) An optional input parameter (`three_d`) converts the geometry to 3d by extruding the coupler geometry in the $z$ direction and adding an oxide layer beneath similar to a [silicon on insulator](https://en.wikipedia.org/wiki/Silicon_on_insulator) (SOI) substrate. A schematic of the coupler design in 3d generated using MayaVi is shown below.
-
+
@@ -162,7 +162,7 @@ grep trans: directional_coupler.out |cut -d , -f2- > directional_coupler.dat;
The transmittance results converted into [insertion loss](https://en.wikipedia.org/wiki/Insertion_loss) for Ports 3 and 4 are shown in the figure below. (There is essentially no flux into Port 2 and thus $|S_{21}|^2$ is not shown in the figure.) When the two waveguide branches are sufficiently separated ($d$ > 0.2 μm), practically all of the input power remains in the top branch and is transferred to Port 3. A small amount of the input power is lost due to scattering into radiative modes within the light cone in the tapered sections where the translational symmetry of the waveguide is broken. This is why the power in Port 3 never reaches exactly 100%. For separation distances of less than approximately 0.2 μm, evanescent coupling of the modes from the top to the lower branch begins to transfer some of the input power to Port 4. For $d$ of 0.13 μm, the input signal is split evenly into Ports 3 and 4. For $d$ of 0.06 μm, the input power is transferred completely to Port 4. Finally, for $d$ of less than 0.06 μm, the evanescent coupling becomes rapidly ineffective and the signal again remains mostly in Port 3.
-
+
@@ -195,7 +195,7 @@ plt.axis('off')
plt.show()
```
-
+
The field profiles confirm that for $d$ of 0.06 μm (Figure 1), the input signal in Port 1 of the top branch is almost completely transferred to Port 4 of the bottom branch. For $d$ of 0.13 μm (Figure 2), the input signal is split evenly between the two branches. Finally, for $d$ of 0.30 μm (Figure 3), there is no longer any evanescent coupling and the signal remains completely in the top branch. The waveguide regions with no fields in Ports 3 and 4 are PML.
@@ -205,7 +205,7 @@ The field profiles confirm that for $d$ of 0.06 μm (Figure 1), the input signal
No (generally). In the single-run calculation of the reflection coefficent $|S_{11}|^2$ which is based on the back-scattered fields in Port 1 (due to the finite taper/bend length which breaks translational symmetry) given the forward-propagating fields of an eigenmode source also in Port 1, slight discretization errors in the eigenmode-coefficient extraction (as described in paragraph 3 of Section 4.2.2 of this [book chapter](https://arxiv.org/abs/1301.5366)) will result in a "noise floor" below which the reflection cannot be measured in this way. This "noise floor" only applies at a fixed resolution — as the resolution is increased, the discretization error in the mode-coefficient calculation goes away, and $|S_{11}|^2$ should approach the "true" reflection from the taper/bend. This is demonstrated in the figure below which shows a plot of the $S_{11}$ and $S_{21}$ reflectance versus resolution. (In these types of calculations, it is important that the source and mode monitor in the same port be separated by *at least several pixels* in order to avoid any overlap due to the grid discretization.)
-
+
@@ -374,4 +374,4 @@ Note the absence of `symmetries` even though, in principle, the ring geometry an
For this ring geometry, Harminv finds a mode with wavelength 1.5490604 μm and $Q$ of 124691.308. The $H_z$ field profile is shown below. As expected, due to the large $Q$ the mode is tightly confined to the ring and exhibits little radiative loss.
-
+
diff --git a/doc/docs/Python_Tutorials/Gyrotropic_Media.md b/doc/docs/Python_Tutorials/Gyrotropic_Media.md
index 97d2faa3c..a2bc358de 100644
--- a/doc/docs/Python_Tutorials/Gyrotropic_Media.md
+++ b/doc/docs/Python_Tutorials/Gyrotropic_Media.md
@@ -79,7 +79,7 @@ plt.show()
```
-
+
We see that the wave indeed rotates in the *x*-*y* plane as it travels.
@@ -119,4 +119,4 @@ plt.show()
As shown in the figure below, the results are in excellent agreement:
-
+
diff --git a/doc/docs/Python_Tutorials/Local_Density_of_States.md b/doc/docs/Python_Tutorials/Local_Density_of_States.md
index f9a80a2ab..6796d167c 100644
--- a/doc/docs/Python_Tutorials/Local_Density_of_States.md
+++ b/doc/docs/Python_Tutorials/Local_Density_of_States.md
@@ -32,7 +32,7 @@ A key feature of the LDOS in this geometry is that it experiences discontinuitie
As shown in the plot below, the results from Meep for both coordinate systems agree well with the analytic theory over the entire range of values of the cavity thickness.
-
+
@@ -314,4 +314,4 @@ plt.ylabel('2Q/(πωW) or LDOS')
plt.show()
```
-
+
diff --git a/doc/docs/Python_Tutorials/Material_Dispersion.md b/doc/docs/Python_Tutorials/Material_Dispersion.md
index 243dc147b..0de2cf917 100644
--- a/doc/docs/Python_Tutorials/Material_Dispersion.md
+++ b/doc/docs/Python_Tutorials/Material_Dispersion.md
@@ -98,7 +98,7 @@ plt.legend(loc='upper right')
plt.show()
```
-
+
@@ -133,7 +133,7 @@ $$\varepsilon(\omega) = \varepsilon(2\pi f) = 2.25 + \frac{1.1^2 \cdot 0.5}{1.1^
The real and imaginary parts of this dielectric function ε(ω) are plotted below:
-
+
@@ -177,7 +177,7 @@ unix% python -u material-dispersion.py | tee material-dispersion.out
we can then `grep` for the frequencies and the computed dielectric function, and plot it. First, let's plot the dispersion relation ω(k) for the real part of ω:
-
+
@@ -186,13 +186,13 @@ The red circles are the computed points from Meep, whereas the blue line is the
Similarly, the computed and analytical real parts of the dielectric function are given by:
-
+
which shows excellent agreement between the analytical (blue line) and numerical (red circles) calculations. The imaginary part, however, is more subtle:
-
+
The blue line is the analytical calculation from above and the red circles are the numerical value from Meep — why is the agreement so poor? There is nothing wrong with Meep, and this is *not* a numerical error. The problem is simply that we are comparing apples and oranges.
diff --git a/doc/docs/Python_Tutorials/Mode_Decomposition.md b/doc/docs/Python_Tutorials/Mode_Decomposition.md
index cb25951af..e12340c1f 100644
--- a/doc/docs/Python_Tutorials/Mode_Decomposition.md
+++ b/doc/docs/Python_Tutorials/Mode_Decomposition.md
@@ -12,7 +12,7 @@ Reflectance of a Waveguide Taper
This example involves computing the reflectance of the fundamental mode of a linear waveguide taper. The structure and the simulation parameters are shown in the schematic below. We will verify that computing the reflectance, the fraction of the incident power which is reflected, using two different methods produces nearly identical results: (1) mode decomposition and (2) [Poynting flux](../Introduction.md#transmittancereflectance-spectra). Also, we will demonstrate that the scaling of the reflectance with the taper length is quadratic, consistent with analytical results from [Optics Express, Vol. 16, pp. 11376-92 (2008)](http://www.opticsinfobase.org/abstract.cfm?URI=oe-16-15-11376).
-
+
@@ -135,7 +135,7 @@ if mp.am_master():
plt.show()
```
-
+
@@ -155,7 +155,7 @@ A pulsed planewave with $E_z$ (or $\mathcal{S}$) polarization spanning wavelengt
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).
-
+
@@ -294,7 +294,7 @@ Each diffraction order corresponds to a single angle. In the figure below, this
The diffraction orders/modes are a finite set of propagating planewaves. The wavevector $k_x$ of these modes can be computed analytically: for a frequency of $\omega$ (in $c=1$ units), these propagating modes are the **real** solutions of $\sqrt{(\omega^2 n^2 - (k_y+2\pi m/\Lambda)^2)}$ where $m$ is the diffraction order (an integer), $\Lambda$ is the periodicity of the grating, and $n$ is the refractive index of the propagating medium. In this example, $n=1$, $k_y=0$, and $\Lambda=10$ μm. Thus, at a wavelength of 0.5 μm there are a total of 20 diffraction orders of which we only computed the first 10. The wavevector $k_x$ is used to compute the angle of the diffraction order as $\cos^{-1}(k_x/(\omega n))$. (The angle can also be equivalently computed as $\sin^{-1}((k_y+2\pi m/\Lambda)/(\omega n))$.) Evanescent modes, those with an imaginary $k_x$, exist for $|m|>20$ but these modes carry no power. Note that currently Meep does not compute the number of propagating modes for you. If the mode number passed to `get_eigenmode_coefficients` is larger than the number of propagating modes at a given frequency/wavelength, MPB's Newton solver will fail to converge and will return zero for the mode coefficient. It is therefore a good idea to know beforehand the number of propagating modes.
-
+
@@ -305,7 +305,7 @@ To convert the diffraction efficiency into transmittance in the $x$ direction (i
Finally, by investigating the transmittance of the zeroth order (at a wavelength of 0.5 μm) in the limit as the grating periodicity approaches zero, we can demonstrate the breakdown of the scalar theory in the wavelength-scale regime which can only be solved using a full-wave method. When the periodicity is much less than the wavelength (i.e., subwavelength), the transmittance can again be solved analytically using effective-medium theory involving a three-layer structure: a layer of the averaged $\varepsilon$ (mean or harmonic mean depending on the polarization $E_z$ or $H_z$) sandwiched between the glass substrate and air. Results are shown in the following figure.
-
+
@@ -627,7 +627,7 @@ For the supercell shown in the right side of the figure, the lattice vectors are
Given a "real" diffracted order specified by $(m_1,m_2)$, we need to determine the equivalent order of the supercell specified by $(n_1,n_2)$ for use in the simulation when computing the mode coefficients. Setting $\vec{k_{SC}}=\vec{k_\parallel}$ and solving for the pair of equations yields: $n_1=m_1$ and $n_2=-m_1+2m_2$.
-
+
To demonstrate this in practice, we will compute the power (an absolute quantity) of the $(0,1)$ order of a triangular lattice of cylindrical rods (height: 0.5 µm, radius: 0.1 µm) on a glass ($n=1.5$) substrate with periodicity of 1.0 µm. Note that this is a 3D simulation. In this example, the plane of incidence is $yz$ and the $E_x$ source therefore corresponds to the $\mathcal{S}$ polarization.
@@ -881,7 +881,7 @@ The phase of the zeroth-diffraction order is simply the angle of its complex mod
The script is run from the shell terminal using: `python binary_grating_phasemap.py -gp 0.35 -gh 0.6 -oddz`. The figure below shows the transmittance spectra (left) and phase map (right). The transmittance is nearly unity over most of the parameter space mainly because of the subwavelength dimensions of the grating. The phase variation spans the full range of $-\pi$ to $+\pi$ at each wavelength but varies weakly with the duty cycle due to the relatively low index of the glass grating. Higher-index materials such as [titanium dioxide](https://en.wikipedia.org/wiki/Titanium_dioxide#Thin_films) (TiO2) generally provide more control over the phase.
-
+
@@ -895,7 +895,7 @@ As a final demonstration of mode decomposition, we compute the diffraction spect
A schematic of the grating geometry is shown below. The grating is a 2d slab in the $xy$-plane with two parameters: birefringence ($\Delta n$) and thickness ($d$). The twisted-nematic grating consists of two layers of thickness $d$ each with equal and opposite rotation angles of $\phi = 70^{\circ}$ for the nematic director. Both gratings contain only three diffraction orders: $m = 0, \pm 1$. The $m=0$ order is linearly polarized and the $m=\pm 1$ orders are circularly polarized with opposite chirality. For the uniaxial grating, the diffraction efficiencies for a mode with wavelength $\lambda$ can be computed analytically: $\eta_0 = \cos^2(\pi\Delta n d/\lambda)$, $\eta_{\pm 1} = 0.5\sin^2(\pi\Delta n d/\lambda)$. The derivation of these formulas is presented in [Optics Letters, Vol. 24, No. 9, pp. 584-6 (1999)](https://www.osapublishing.org/ol/abstract.cfm?uri=ol-24-9-584). We will verify these analytic results and also demonstrate that the twisted-nematic grating produces a broader bandwidth response for the ±1 orders than the homogeneous uniaxial grating. An important property of these polarization gratings for e.g. display applications is that for a circular-polarized input planewave and phase delay ($\Delta n d/\lambda$) of nearly 0.5, there is only a single diffraction order (+1 or -1) with *opposite* chiraity to that of the input. This is also demonstrated below.
-
+
@@ -1071,7 +1071,7 @@ plt.title("bilayer twisted-nematic grating")
plt.show()
```
-
+
The left figure shows good agreement between the simulation results and analytic theory for the homogeneous uniaxial grating. Approximately 6% of the power in the input planewave is lost due to reflection from the grating. This value is an average over all phase delays. The total transmittance is therefore around 94%. The twisted-nematic grating, with results shown in the right figure, produces ±1 diffraction orders with nearly-constant peak transmittance over a broader bandwidth around $\Delta nd/\lambda=0.5$ than the homogeneous uniaxial polarization grating. This is consistent with results from the reference. The average reflectance and transmittance for the twisted-nematic grating are similar to those for the homogeneous uniaxial grating.
@@ -1096,7 +1096,7 @@ Note: when imparting a phase offset using a complex `amplitude`, it is *not* nec
The figure below shows a snapshot of $E_z$ for four different cases: phase delays ($\Delta nd/\lambda$) of 0.5 and 1.0, and circular-polarized planewave sources of $E_z + iE_y$ and $E_z - iE_y$. The empty regions on the cell sides are PMLs. The thin solid black line denotes the boundary between the grating (on the left) and air. As expected, for $\Delta nd/\lambda=0.5$ there is just a single ±1 diffraction order which depends on the chirality of the input planewave (this is not the case for a linear-polarized planewave). The angle of this diffracted order (±4.8°) agrees with the analytic result. Snapshots of $E_y$ are similar.
-
+
For computing the mode coefficient of an [elliptically polarized](https://en.wikipedia.org/wiki/Elliptical_polarization) mode in 3d, one approach is to first compute the mode coefficients of two orthogonal linearly polarized modes ($\mathcal{S}$ and $\mathcal{P}$ polarizations) separately using the [`DiffractedPlanewave`](../Python_User_Interface.md#diffractedplanewave) object which is passed as the `bands` parameter to `get_eigenmode_coefficients`. The complex mode coefficients for these two polarizations can then be combined in post-processing via a linear combination to compute the mode coefficient for any arbitrary elliptically polarized mode. Alternatively, you can specify an elliptical polarization directly in a single `DiffractedPlanewave` object by supplying both $\mathcal{S}$ and $\mathcal{P}$ amplitudes with the desired relative phase.
diff --git a/doc/docs/Python_Tutorials/Multilevel_Atomic_Susceptibility.md b/doc/docs/Python_Tutorials/Multilevel_Atomic_Susceptibility.md
index 8ebbbdb59..102ef50eb 100644
--- a/doc/docs/Python_Tutorials/Multilevel_Atomic_Susceptibility.md
+++ b/doc/docs/Python_Tutorials/Multilevel_Atomic_Susceptibility.md
@@ -91,7 +91,7 @@ sim.run(mp.after_time(endt-250, print_field), until=endt)
The spectra of the field intensity is shown below.
-
+
@@ -104,9 +104,9 @@ For two-level gain media, $\gamma_\parallel = \gamma_{12} + \gamma_{21}$. We can
By varying $N_0$ or the pumping rate $R_p$, we can change the total gain available in the cavity. This is used to find the laser's modal intensities as a function of the strength of the gain. We can compare the simulated modal intensity with SALT as well as an independent FDTD solver based on the Maxwell-Bloch equations. All three methods produce results with good agreement close to the first lasing threshold.
-
+
Further increasing the gain continues to yield good agreement.
-
+
diff --git a/doc/docs/Python_Tutorials/Near_to_Far_Field_Spectra.md b/doc/docs/Python_Tutorials/Near_to_Far_Field_Spectra.md
index af3119df7..df1fe6fb9 100644
--- a/doc/docs/Python_Tutorials/Near_to_Far_Field_Spectra.md
+++ b/doc/docs/Python_Tutorials/Near_to_Far_Field_Spectra.md
@@ -14,7 +14,7 @@ In this example, we compute the [radiation pattern](https://en.wikipedia.org/wik
The simulation geometry is shown in the following schematic.
-
+
In the first part of the simulation, we define the cell and source as well as the near field and flux regions. Since we are using a pulsed source (with center wavelength of 1 μm), the fields are timestepped until they have sufficiently decayed away.
@@ -166,7 +166,7 @@ ax.set_rlabel_position(22)
plt.show()
```
-
+
### Antenna above a Perfect Electric Conductor Ground Plane
@@ -180,7 +180,7 @@ We can validate the radiation pattern computed by Meep using analytic theory. Th
The simulation script is in [examples/antenna_pec_ground_plane.py](https://github.com/NanoComp/meep/blob/master/python/examples/antenna_pec_ground_plane.py).
-
+
@@ -521,7 +521,7 @@ plt.show()
The phasemap is shown below. The left figure shows the transmittance which is nearly unity for all values of the duty cycle; the Fresnel transmittance is 0.96 for the glass-air interface. This is expected since the periodicity is subwavelength. The right figure shows the phase. There is a subregion in the middle of the plot spanning the duty-cycle range of roughly 0.16 to 0.65 in which the phase varies continuously over the full range of -2π to 0. This structural regime is used to design the supercell lens.
-
+
@@ -566,14 +566,14 @@ plt.show()
Shown below is the supercell lens design involving 201 unit cells. Note that even though periodic boundaries are used in the supercell calculation (via the `k_point`), the choice of cell boundaries in the *y* (or longitudinal) direction is *irrelevant* given the finite length of the lens. For example, PMLs could also have been used (at the expense of a larger cell). Although [`add_near2far`](../Python_User_Interface.md#near-to-far-field-spectra) does support periodic boundaries (via the `nperiods` parameter), it is not necessary for this particular example.
-
+
The far-field energy-density profile is shown below for the three lens designs. As the number of unit cells increases, the focal spot becomes sharper and sharper. This is expected since the longer the focal length, the bigger the lens required to demonstrate focusing (which means more unit cells). In this example, the largest lens design contains 801 unit cells which corresponds to 0.24 mm or 1.2X the focal length.
-
+
@@ -756,7 +756,7 @@ plt.tight_layout(pad=0.5)
plt.show()
```
-
+
@@ -771,7 +771,7 @@ Finally, we can validate the results for the diffraction spectra of a finite gra
The simulation setup is shown in the schematic below. The binary grating has $\Lambda = 1$ μm at a wavelength of 0.5 μm via a normally-incident planewave pulse (which must [extend into the PML region in order to span the entire width of the cell](../Perfectly_Matched_Layer.md#planewave-sources-extending-into-pml)). The grating structure is terminated with a flat-surface padding in order to give the scattered field space to decay at the edge of the cell.
-
+
@@ -907,10 +907,10 @@ else:
Results are shown for two finite gratings with 5 and 20 periods.
-
+
-
+
@@ -925,7 +925,7 @@ Truncation Errors from a Non-Closed Near-Field Surface
For this demonstration, we will compute the far-field spectra of a resonant cavity mode in a holey waveguide (a structure introduced in [Tutorial/Resonant Modes and Transmission in a Waveguide Cavity](Resonant_Modes_and_Transmission_in_a_Waveguide_Cavity.md)) and demonstrate that these fields are *exactly* equivalent to the actual DFT fields at the same location. A schematic of the simulation setup generated using [`plot2D`](../Python_User_Interface.md#data-visualization) is shown below.
-
+
The script is in [examples/cavity-farfield.py](https://github.com/NanoComp/meep/blob/master/python/examples/cavity-farfield.py). The notebook is [examples/cavity-farfield.ipynb](https://nbviewer.jupyter.org/github/NanoComp/meep/blob/master/python/examples/cavity-farfield.ipynb).
@@ -1060,9 +1060,9 @@ A closed near-field surface will still disagree with a brute-force far-field cal
In this example, to demonstrate agreement between the far fields and DFT fields, there are two requirements: (1) the cell size in the $x$ direction via `dpad` needs to be sufficiently large in order to minimize the impact of the spurious radiation from the edge of the near-field surface and (2) the far-field region needs to be sufficiently close to the near-field surface to minimize discrepancies caused by numerical dispersion.
-
+
When these two conditions are not met as in the example below involving a small `dpad` and large `d2`, the error from the finite truncation and numerical dispersion can be large and therefore result in a significant mismatch between the far fields computed using the near-to-far field transformation versus the actual DFT fields at the same location.
-
+
diff --git a/doc/docs/Python_Tutorials/Optical_Forces.md b/doc/docs/Python_Tutorials/Optical_Forces.md
index 2c9f368f1..189c761f9 100644
--- a/doc/docs/Python_Tutorials/Optical_Forces.md
+++ b/doc/docs/Python_Tutorials/Optical_Forces.md
@@ -4,7 +4,7 @@
This tutorial demonstrates Meep's ability to compute classical forces via the [Maxwell stress tensor](https://en.wikipedia.org/wiki/Maxwell_stress_tensor). The geometry consists of two identical, parallel, silicon waveguides with square cross section in vacuum. A schematic of the geometry is shown below. Due to the parallel orientation of the waveguides (propagation axis along $z$ and separation in $x$), the two modes can be chosen to be either symmetric or anti-symmetric with respect to an $x$ mirror-symmetry plane between them. As the two waveguides are brought closer and closer together, their modes couple and give rise to a gradient force that is *transverse* to the waveguide axis (i.e., in the $x$ direction). This is different from [radiation pressure](https://en.wikipedia.org/wiki/Radiation_pressure) which involves momentum exchange between photons and is longitudinal in nature (i.e., along the $z$ direction). An interesting phenomena that occurs for this coupled waveguide system is that the force can be tuned to be either attractive or repulsive depending on the relative phase of the two modes. This tutorial will demonstrate this effect.
-
+
The gradient force $F$ on each waveguide arising from the evanescent coupling of the two waveguide modes can be computed analytically:
@@ -130,7 +130,7 @@ plt.show()
The following figure shows the $E_y$ mode profiles at a waveguide separation distance of 0.1 μm. This figure was generated using the [`plot2D`](../Python_User_Interface.md#data-visualization) routine and shows the source and flux monitor (red hatches), force monitors (blue lines), and PMLs (green hatches) surrounding the cell. From the force spectra shown above, at this separation distance the anti-symmetric mode is repulsive whereas the symmetric mode is attractive.
-
+
The MPB simulation is in [examples/parallel-wvgs-mpb.py](https://github.com/NanoComp/meep/blob/master/python/examples/parallel-wvgs-mpb.py). There are important differences related to the coordinate dimensions between the MPB and Meep scripts. In the MPB script, the 2d cell is defined using the $yz$ plane, the waveguide propagation axis is $x$, and the waveguide separation axis is $y$. As a consequence, the `num_bands` parameter is always `1` since the $y$ parity of the mode can be defined explicitly (i.e., `run_yodd_zodd` vs. `run_yeven_zodd`). This is different from the Meep script since Meep requires that a 2d cell be defined in the $xy$ plane. MPB has no such requirement.
diff --git a/doc/docs/Python_Tutorials/Resonant_Modes_and_Transmission_in_a_Waveguide_Cavity.md b/doc/docs/Python_Tutorials/Resonant_Modes_and_Transmission_in_a_Waveguide_Cavity.md
index be6ebfc8a..8104c44f6 100644
--- a/doc/docs/Python_Tutorials/Resonant_Modes_and_Transmission_in_a_Waveguide_Cavity.md
+++ b/doc/docs/Python_Tutorials/Resonant_Modes_and_Transmission_in_a_Waveguide_Cavity.md
@@ -4,7 +4,7 @@
In this example, we will consider the 2d structure shown below, which is based on a system considered in Chapter 7 of [Photonic Crystals: Molding the Flow of Light (second edition)](http://ab-initio.mit.edu/book). In particular, there are three basic ideas behind this structure, which we briefly summarize.
-
+
First, by taking a dielectric wavgeuide and perforating it with a periodic sequence of holes, we form a kind of **photonic crystal**: there are still index-guided modes propagating losslessly down the periodic waveguide, but there is also a partial photonic band gap: a range of frequencies in which *no guided modes* exist.
@@ -162,9 +162,9 @@ which takes a few seconds as we need to wait for the cavity mode to decay away.
unix% h5topng holey-wvg-cavity-eps-000000.00.h5
unix% h5topng -Zc dkbluered holey-wvg-cavity-hz-slice.h5
```
-
+
-
+
The $H_z$ slice in which time = vertical is interesting, because we can see the pulse propagating to the right, bouncing off of the holes, and also exciting a resonant mode in the cavity that sits in the center for a long time as it starts slowly leaking to the right.
@@ -184,7 +184,7 @@ unix% grep flux1: holey-wvg-cavity0.out > flux0.dat
which we then import into our plotting program, divide the two fluxes, and get:
-
+
The band gap is clearly visible as the range of very low transmission, and in the middle of the band gap is a sharp peak corresponding to the resonant mode trapped in the defect. The inset enlarges this peak, and shows that we didn't use quite enough frequency points to capture the whole shape although we could fit to a Lorentzian if we wanted. At the edges of the band gaps, the transmission goes up in broad Fabry-Perot resonance peaks which we will examine in more detail below. There is also some high-frequency oscillation visible at the left of the plot, which is a numerical artifact due to our pulse not having enough amplitude in that range.
@@ -251,7 +251,7 @@ unix% h5topng -RZc dkbluered -C holey-wvg-cavity-eps-000000.00.h5 holey-wv
unix% convert holey-wvg-cavity-hz-*.png holey-wvg-cavity-hz.gif
```
-
+
The mode has a frequency of 0.235, just as we saw in the transmission spectrum, and a $Q$ of 373 which we could have also found by fitting the transmission spectrum. This lifetime $Q$ includes two independent decay channels: light can decay from the cavity into the waveguide with lifetime $Q_w$, or it can radiate from the cavity into the surrounding air with lifetime $Q_r$, where
@@ -266,7 +266,7 @@ unix% python holey-wvg-cavity.py -r -N 5 |grep harminv
...
```
-
+
The results, shown above, are exactly what we expected: at first, an exponential increase of $Q$ with `N`, and then a saturation at $Q_r \approx 8750$. However, when we look at the Harminv output for larger `N`, something strange happens — it starts to find *more modes*! For example, at `N=16`, the output is:
@@ -283,7 +283,7 @@ What is this extra mode at $ω=0.32823$? This is right around the **edge of the
unix% python holey-wvg-cavity.py -r -sy 12 -fcen 0.328227374843021 -df 0.01 -N 16
```
-
+
From the image, the field is clearly localized around the defect in the center as opposed to being spread out evenly in the crystal like a band-edge state would be. In the defect, the pattern is higher order than the previous mode. It has an extra pair of nodes in the $y$ direction.
@@ -292,7 +292,7 @@ Band Diagram
Finally, we consider a smaller, more abstract calculation that we really should have done first. In particular, we compute the **band diagram** of the infinite periodic waveguide by itself with no defects. The structure is shown below. This is very similar to the types of calculations that [MPB](https://mpb.readthedocs.io) performs, but with a different method that has its own strengths and weaknesses. By analyzing what solutions can propagate in the periodic structure, one gains fundamental insight into the aperiodic structures above.
-
+
Let us briefly review the problem. In a periodic system of this sort, the eigen-solutions can be expressed in the form of *Bloch modes*: a periodic *Bloch envelope* multiplied by a planewave $\exp[i(\mathbf{k}\cdot\mathbf{x}-ω t)]$, where **k** is the *Bloch wavevector*. We wish to find the *bands* $ω(\mathbf{k})$. In this case, there is only *one* direction of periodicity, so we only have one wavevector component $k_x$. Moreover, the solutions are periodic functions of this wavevector: for a unit-period structure, $k_x$ and $k_x+2\pi$ are redundant. Also, $k_x$ and $-k_x$ are redundant by time-reversal symmetry, so we only need to look for solutions in the *irreducible Brillouin zone* from $k_x=0$ to $k_x=\pi$.
@@ -379,7 +379,7 @@ unix% grep freqs-im: holey-wvg-bands.out > fim.dat
Plotting the real parts of ω, where the light cone ω > *ck* is shaded gray, we find:
-
+
The gray shaded region is the **light cone**, $ω > ck_x$, which is the region corresponding to modes that are extended in the air surrounding the waveguide. Below the light cone, we see several discrete *guided bands*, which must have field patterns localized to the vicinity of the waveguide. The imaginary part of ω for bands below the light cone is very small, due to either numerical error or the finite computational cell size. Some tiny portion of the guided mode overlaps the PML. Note the band gap between the first and second guided mode, from about 0.2 to 0.3.
@@ -398,11 +398,11 @@ It is usually a good idea to examine the field patterns for any modes that you a
+ $k_x=0.3$, $ω=0.8838-0.0018i$ leaky mode
+ $k_x=0.25$, $ω=0.2506$ light-cone (extended) mode
-
-
-
-
-
+
+
+
+
+
- From the top, the first two pictures show the first two guided bands underneath the light cone at $k_x=0.4$. Note that the second guided band is propagating to the *left*, which is due to its negative slope (note, however, that there is a corresponding right-propagating mode at $k_x=-0.4$). Note that they are strongly (exponentially) localized to the waveguide, as they should be.
diff --git a/doc/docs/Python_Tutorials/Third_Harmonic_Generation.md b/doc/docs/Python_Tutorials/Third_Harmonic_Generation.md
index fb8c7d4be..46717198c 100644
--- a/doc/docs/Python_Tutorials/Third_Harmonic_Generation.md
+++ b/doc/docs/Python_Tutorials/Third_Harmonic_Generation.md
@@ -80,7 +80,7 @@ sim.display_fluxes(trans)
In a linear calculation, we normalize the transmission against some reference spectrum, but in this case there is no obvious normalization so we will just plot the raw data for several values of `k` (i.e. of χ$^{(3)}$):
-
+
For small values of χ$^{(3)}$, we see a peak from our source at ω=1/3 and another peak precisely at the third-harmonic frequency 3ω=1. As the χ$^{(3)}$ gets larger, frequency-mixing *within* the peaks causes them to broaden, and finally for χ$^{(3)}=1$ we start to see a noisy, broad-spectrum transmission due to the phenomenon of **modulation instability**. Notice also that at around $10^{-13}$ the data looks weird; this is probably due to our finite simulation time, imperfect absorbing boundaries, etcetera. We haven't attempted to analyze it in detail for this case.
@@ -130,7 +130,7 @@ harmonics:, 1e-16, 1.0, 225.25726603587043, 5.026979706160964e-16
That is, the linear transmission is 225.25726603587043 at ω, so we'll divide by this value and plot the fractional transmission at ω and 3ω as a function of χ$^{(3)}$ on a log-log scale:
-
+
As can be shown from coupled-mode theory or, equivalently, follows from [Fermi's golden rule](https://en.wikipedia.org/wiki/Fermi's_golden_rule), the third-harmonic power must go as the *square* of χ$^{(3)}$ as long as the nonlinearity is weak (i.e. in the first Born approximation limit, where the ω source is not depleted significantly). This is precisely what we see on the above graph, where the slope of the black line indicates an exact quadratic dependence, for comparison. Once the nonlinearity gets strong enough, however, this approximation is no longer valid and the dependence is complicated.
diff --git a/doc/docs/Python_User_Interface.md b/doc/docs/Python_User_Interface.md
index a6959c85f..0a8d3150e 100644
--- a/doc/docs/Python_User_Interface.md
+++ b/doc/docs/Python_User_Interface.md
@@ -610,7 +610,7 @@ demonstrated in the following image for two
[Cylinder](#cylinder) objects (the simulation script is in
[examples/phase_in_material.py](https://github.com/NanoComp/meep/blob/master/python/examples/phase_in_material.py)).
-
+
@@ -3771,7 +3771,7 @@ ax.set_aspect('equal')
plt.show()
```
-
+
**Computing Quantities Defined by Integrals of Field-Dependent Functions Over Grid Regions**
@@ -4452,7 +4452,7 @@ on the `size` property of the `Block` object as shown in the following example f
with $N_x=5$ and $N_y=4$. $N_z=0$ implies that the `MaterialGrid` is extruded in the $z$ direction.
The grid points are defined at the corners of the voxels.
-
+
Elements of the `weights` array must be in the range [0,1] where 0 is `medium1` and 1 is `medium2`.
The `weights` array is used to define a linear interpolation from `medium1` to `medium2`.
diff --git a/doc/docs/Scheme_Tutorials/Basics.md b/doc/docs/Scheme_Tutorials/Basics.md
index ec8caaf6e..731f81cc6 100644
--- a/doc/docs/Scheme_Tutorials/Basics.md
+++ b/doc/docs/Scheme_Tutorials/Basics.md
@@ -58,7 +58,7 @@ We can add the waveguide. Most commonly, the structure is specified by a `list`
The waveguide is specified by a *block* (parallelepiped) of size $\infty \times 1 \times \infty$, with ε=12, centered at (0,0) which is the center of the cell. By default, any place where there are no objects there is air (ε=1), although this can be changed by setting the `default-material` variable. The resulting structure is shown below.
-
+
We have the structure and need to specify the current sources using the [`sources`](../Scheme_User_Interface.md#source) object. The simplest thing is to add a single point source $J_z$:
@@ -110,7 +110,7 @@ unix% h5topng -S3 -Zc dkbluered -a yarg -A eps-000000.00.h5 ez-000200.0
Briefly, the `-Zc dkbluered` makes the color scale go from dark blue (negative) to white (zero) to dark red (positive), and the `-a/-A` options overlay the dielectric function as light gray contours. This results in the image:
-
+
We see that the the source has excited the waveguide mode, but has also excited radiating fields propagating away from the waveguide. At the boundaries, the field quickly goes to zero due to the PML layers. If we look carefully, we see something else — the image is "speckled" towards the right side. This is because, by turning on the current abruptly at $t=0$, we have excited high-frequency components (very high order modes), and we have not waited long enough for them to die away; we'll eliminate these in the next section by turning on the source more smoothly.
@@ -140,7 +140,7 @@ Then let's set up the bent waveguide, in a slightly bigger cell, via:
Note that we have *two* blocks, both off-center to produce the bent waveguide structure pictured at right. As illustrated in the figure, the origin (0,0) of the coordinate system is at the center of the cell, with positive $y$ being downwards in `h5topng`, and thus the block of size 12$\times$1 is centered at (-2,-3.5). Also shown in green is the source plane at $x=-7$ which is shifted to $y=-3.5$ so that it is still inside the waveguide.
-
+
There are a couple of items to note. First, a point source does not couple very efficiently to the waveguide mode, so we'll expand this into a line source the same width as the waveguide by adding a `size` property to the source. An eigenmode source can also be used which is described in [Tutorial/Optical Forces](Optical_Forces.md). Second, instead of turning the source on suddenly at t=0 which excites many other frequencies because of the discontinuity, we will ramp it on slowly. Meep uses a hyperbolic tangent (tanh) turn-on function over a time proportional to the `width` of 20 time units which is a little over three periods. Finally, just for variety, we'll specify the vacuum `wavelength` instead of the `frequency`; again, we'll use a wavelength such that the waveguide is half a wavelength wide.
@@ -183,11 +183,11 @@ unix% convert ez.t*.png ez.gif
We are using an animated GIF format for the output. This results in the following animation:
-
+
-
+
-
+
It is clear that the transmission around the bend is rather low for this frequency and structure — both large reflection and large radiation loss are clearly visible. Moreover, since we are operating just barely below the cutoff for single-mode behavior, we are able to excite a second *leaky* mode after the waveguide bend, whose second-order mode pattern (superimposed with the fundamental mode) is apparent in the animation. At right, we show a field snapshot from a simulation with a larger cell along the $y$ direction, in which you can see that the second-order leaky mode decays away, leaving us with the fundamental mode propagating downward.
@@ -391,7 +391,7 @@ unix% grep flux1: bend.out > bend.dat
We import them to Octave/Matlab (using its `dlmread` command), and plot the results:
-
+
What are we plotting here? The transmittance is the transmitted flux (second column of `bend.dat`) divided by the incident flux (second column of `bend0.dat`), to give us the *fraction* of power transmitted. The reflectance is the reflected flux (third column of `bend.dat`) divided by the incident flux (second column of `bend0.dat`). We also have to multiply by -1 because all fluxes in Meep are computed in the positive-coordinate direction by default, and we want the flux in the $-x$ direction. Finally, the scattered loss is simply $1-transmittance-reflectance$.
@@ -550,7 +550,7 @@ ylabel("wavelength (μm)");
title("reflectance (analytic)");
```
-
+
Mie Scattering of a Lossless Dielectric Sphere
----------------------------------------------
@@ -562,7 +562,7 @@ The scattering cross section ($\sigma_{scat}$) is the scattered power in all dir
A schematic of the 2d cross section at $z = 0$ of the 3d cell is shown below.
-
+
The simulation script is in [examples/mie-scattering.ctl](https://github.com/NanoComp/meep/blob/master/scheme/examples/mie-scattering.ctl). As an estimate of runtime, the [parallel simulation](../Parallel_Meep.md) on a machine with three Intel Xeon 4.20 GHz cores takes less than five minutes.
@@ -709,7 +709,7 @@ The incident intensity (`intensity`) is the flux in one of the six monitor plane
Results are shown below. Overall, the Meep results agree well with the analytic theory.
-
+
Finally, for the case of a *lossy* dielectric material (i.e. complex refractive index) with non-zero absorption, the procedure to obtain the scattering efficiency is the same. The absorption efficiency is the ratio of the absorption cross section ($\sigma_{abs}$) to the cross sectional area of the sphere. The absorption cross section is the total absorbed power divided by the incident intensity. The absorbed power is simply flux into the same box as for the scattered power, but *without* subtracting the incident field (and with the opposite sign, since absorption is flux *into* the box and scattering is flux *out of* the box): omit the `load-minus-flux` calls. The extinction cross section ($\sigma_{ext}$) is simply the sum of the scattering and absorption cross sections: $\sigma_{scat}+\sigma_{abs}$.
@@ -947,7 +947,7 @@ There is one important item to note: in order to eliminate discretization artifa
A schematic of the simulation layout shows the line source (red), PMLs (green hatch region), `dft-flux` box (solid blue contour line), and `dft-fields` surface (blue hatch region).
-
+
The spatial map of the absorbed power density is generated from the DFT fields in `dft-fields-cylinder.h5` using the Octave/Matlab script below. The figures shows that most of the absorption occurs in a small region near the back surface of the cylinder (i.e., on the opposite side of the incident planewave).
@@ -986,7 +986,7 @@ print -dpng 'power_density_map.png';
```
-
+
Finally, the two values for the total absorbed power are nearly equivalent: 0.13120421825956843 (`dft-fields`) vs. 0.13249534167200672 (`dft-flux`). The relative error between the two methods is ~1.0%.
@@ -1088,9 +1088,9 @@ unix% convert ring-ez-*.png ring-ez-0.118.gif
The resulting animations for (from left to right) 0.118, 0.147, and 0.175, are below, in which you can clearly see the radiating fields that produce the losses:
-
-
-
+
+
+
Each of these modes is, of course, doubly-degenerate according to the representations of the $C_{\infty\mathrm{v}}$ symmetry group. The other mode is simply a slight rotation of this mode to make it *odd* through the $x$ axis, whereas we excited only the *even* modes due to our source symmetry. Equivalently, one can form clockwise and counter-clockwise propagating modes by taking linear combinations of the even/odd modes, corresponding to an angular $\phi$ dependence $e^{\pm i m\phi}$ for m=3, 4, and 5 in this case.
@@ -1153,7 +1153,7 @@ mayavi2 -d epsilon.vtk -m IsoSurface &> /dev/null &
```
-
+
diff --git a/doc/docs/Scheme_Tutorials/Casimir_Forces.md b/doc/docs/Scheme_Tutorials/Casimir_Forces.md
index f39b3b27d..191747e49 100644
--- a/doc/docs/Scheme_Tutorials/Casimir_Forces.md
+++ b/doc/docs/Scheme_Tutorials/Casimir_Forces.md
@@ -23,7 +23,7 @@ In this section, we introduce the equations and basic considerations involved in
The general setup for a Casimir force computation by integrating the Maxwell stress tensor on a surface *S* around an object is shown in the following figure:
-
+
The goal is to determine the Casimir force on one object (shown in red) due to the presence of other objects (blue).
@@ -72,7 +72,7 @@ Example: Two-Dimensional Blocks
In this section we calculate the Casimir force in the two-dimensional Casimir piston configuration ([Rodriguez et. al](http://math.mit.edu/~stevenj/papers/RodriguezIb07.pdf)) shown below:
-
+
This is described in [rod-plates.ctl](http://ab-initio.mit.edu/~mccauley/casimir-examples/rods-plates.ctl). The dashed red lines indicate the surface $S$. This system consists of two metal $a\times a$ squares in between metallic sidewalls. To run a simulation in which the blocks are (nondispersive) dielectrics one can simply change their materials in the definitions as in a normal Meep simulation. For dispersive dielectrics a few extra steps are needed, which is discussed in a later section.
@@ -144,7 +144,7 @@ $$f_n(x) = \sqrt{\frac{c_n}{L}} \cos \left(\frac{n\pi x}{L}\right), ~n = 0,1,\ld
where $c_n = 1$ if $n=0$ and $c_n=2$ otherwise, $L$ is the side length (if each side has a different length, then the functions $f_n(x)$ will differ for each side). An illustration of these functions for the system under consideration, compared to point sources, is shown below:
-
+
For the simulation, we must truncate the sum over $n$ to some finite upper limit `n-max`. Typically, a value of 10 is sufficient to get results to within 1%:
@@ -156,7 +156,7 @@ For the simulation, we must truncate the sum over $n$ to some finite upper limit
To illustrate the field profiles, below we show four snapshots at different times for what we term $\Gamma^E_{yy;n=2}(\mathbf{x},t)$, the $y$-component of the electric field response to a $y$-polarized current source with spatial dependence $f_2(x)$
-
+
As the fields continue to propagate, the finite conductivity `Sigma` causes the fields to decay rapidly. By $T\simeq 20$ the fields have all but vanished. Note that the user is not confined to use this Cosine basis, but that this type is already built into meep and therefore offers the greatest convenience.
@@ -198,7 +198,7 @@ To find the casimir force, one simply iterates over the parameter lists construc
The result, when sampled over many values of $h$, is a force curve that varies non monotonically in $h$:
-
+
Here the force is measured relative to the value obtained by the PFA (proximity-force approximation), a simple approximation for the force used in lieu of an exact analytic expression or a numerically accurate value. As is clear from the figure, the behavior of the force deviates significantly from the PFA, indicating the need for accurate algorithms for computing the Casimir force.
@@ -219,7 +219,7 @@ This numerical artifact can be removed by a simple procedure, called vacuum subt
The procedure for the double blocks case is illustrated below:
-
+
In an ideal case of infinite spatial resolution, only the first term is nonzero. However, due to discretization effects, for finite resolution they can be quite large and will depend on the source surface. The total vacuum-subtracted force, however, will still be well-behaved for finite resolution.
@@ -367,7 +367,7 @@ A lossless dielectric material with a single Lorentzian resonance, e.g., Silicon
-$\epsilon(\xi) = \epsilon_f + \frac{C \xi_0^2}{\omega_0^2 - \xi^2}$
+$$\epsilon(\xi) = \epsilon_f + \frac{C \xi_0^2}{\omega_0^2 - \xi^2}$$
@@ -377,7 +377,7 @@ The conductivity mapping $\omega^2 = \xi^2 + i \sigma \xi$ must be applied to al
-$\epsilon (\xi) = \epsilon_f + \frac{C \xi_0^2}{\omega_0^2 - \xi^2 - i\sigma \xi}$
+$$\epsilon (\xi) = \epsilon_f + \frac{C \xi_0^2}{\omega_0^2 - \xi^2 - i\sigma \xi}$$
@@ -407,7 +407,7 @@ Example: Z-Invariant Geometry
An example geometry in 3d which is $z$-invariant is shown below:
-
+
This example is also treated in the [rods-plates.ctl](http://ab-initio.mit.edu/~mccauley/casimir-examples/rods-plates.ctl). Now there is another parameter in the fields, $k_z$, the out-of-plane wavevector component of the fields. The field dependence is now of the form $\mathbf{E}(x,y,z) = \mathbf{E}(x,y) e^{i\pi k_z z}$. Consequently, an integral over the stress tensor will involve an integral over $k_z$, where for each $k_z$, the green's function can be determined by a two-dimensional computation. Each two-dimensional computation gives a force $\mathbf{F}^{2D}(k_z)$, and the total force is expressed as an integral:
@@ -461,7 +461,7 @@ Example: Cylindrical Symmetry
For systems with cylindrical symmetry, the Casimir force computation can be reduced as in the case of $z$-invariant geometries to a sum of forces obtained from two-dimensional computations. An example is a recently-discovered system [Levin et. al.](https://journals.aps.org/prl/abstract/10.1103/PhysRevLett.105.090403) that exhibits a repulsive Casimir force between vacuum-separated dielectrics. This system is shown below:
-
+
The hole in the bottom plane, coupled with the high degree of anisotropy of the upper elliptical particle, results in a repulsive force when the particle is centered above the hole. This system is simulated in [repulsive-particle.ctl](http://ab-initio.mit.edu/~mccauley/casimir-examples/repulsive-particle.ctl). The size parameters used in the ctl file are noted on the figure above.
@@ -495,7 +495,7 @@ Example: Three-Dimensional Periodic Systems
Three-dimensional periodic systems are another example of systems that can be easily analyzed with Meep. In this example, we consider the Casimir force between a periodic array of dielectric spheres and a metallic plate, shown below and simulated in [periodic-sphere-plate.ctl](http://ab-initio.mit.edu/~mccauley/casimir-examples/periodic-sphere-plate.ctl):
-
+
In this example, the plate can either be perfect metal, or dispersive gold (the default). Set `dispersion?` to false to get a perfect metal plate. We denote the $z$-direction to be the vector normal to the plate, and the $x$ and $y$ directions to be parallel to the plate. In this case we have two directions of Bloch periodicity, $k_x$ and $k_y$. However, unlike the previous case of $z$-invariance, here the source surface $S$ intersects the periodic bounding surface.
diff --git a/doc/docs/Scheme_Tutorials/Custom_Source.md b/doc/docs/Scheme_Tutorials/Custom_Source.md
index beb2a1563..ce4c3cf5a 100644
--- a/doc/docs/Scheme_Tutorials/Custom_Source.md
+++ b/doc/docs/Scheme_Tutorials/Custom_Source.md
@@ -14,7 +14,7 @@ In addition to the two source time profiles of a [continuous wave](../Scheme_Use
This tutorial example involves computing the radiated [flux](../Introduction.md#transmittancereflectance-spectra) from $N=10$ dipole emitters of a 2d LED-like periodic structure with a thin (1d) light-emitting layer. A schematic of the unit cell geometry and simulation layout is shown below. A silver (Ag) back reflector is used to direct nearly all the flux upwards into the $+y$ direction. PML is used to terminate the air region at the top of the cell. (Note: PML is not necessary at the bottom of the cell due to the Ag layer which is effectively a lossless mirror with [skin depth](https://en.wikipedia.org/wiki/Skin_effect) of a few nanometers at a wavelength of 1 μm.) The emitting layer is placed within a lossless dielectric substrate with wavelength-independent refractive index of 3.45.
-
+
One can take two different approaches to computing the radiated flux based on the type of emitter: (1) random or (2) deterministic. In Method 1 (brute-force Monte Carlo), each emitter is a white-noise dipole: every timestep for every dipole is an independent random number. A single run involves all $N$ dipoles which are modeled using a `custom-src`. The stochastic results for the radiated flux are averaged over multiple trials/iterations via [Monte Carlo sampling](https://en.wikipedia.org/wiki/Monte_Carlo_method). Method 2 exploits the property of [linear time-invariance](https://en.wikipedia.org/wiki/Linear_time-invariant_system) of the materials/geometry and involves a sequence of $N$ separate runs each with a single deterministic dipole (i.e., pulse time profile, `gaussian-src`) at different positions in the emitting layer. Because dipoles at different positions are uncorrelated, the radiated flux from the ensemble is simply the average of all the individual iterations. The two approaches converge towards identical results, but Method 1 is more computationally expensive than Method 2 due to the much larger number of trials/iterations ($\gg N$) required to attain low noise variance. (Even more sophisticated deterministic methods exist to reduce the number of separate simulations, especially at high resolutions; for example, replacing the point-dipole sources with a [rapidly converging set of smooth basis functions](https://journals.aps.org/pra/abstract/10.1103/PhysRevA.81.012119), or fancier methods that exploit [trace-estimation methods](http://doi.org/10.1103/PhysRevB.92.134202) and/or transform volumetric sources to [surface sources](http://doi.org/10.1103/PhysRevB.88.054305).)
@@ -159,13 +159,13 @@ legend('Method 1','Method 2');
Results for Method 1 for three different numbers of trials/iterations (10, 50, and 500) are shown in the following three figures. Each trial/iteration involves two runs: one each for the flat and textured surface. As the number of trials/iterations is increased, the "noisiness" in the plot is gradually reduced. However, the total runtime increases significantly.
-
+
The next figure shows a comparison of the normalized radiated flux for Method 1 (500 trials) and 2 (20 runs; 10 runs each for the flat and textured surface). The results show good agreement over the entire bandwidth spectrum. The Method 1 (labeled "Monte Carlo") results required almost *four days* whereas the Method 2 (labeled "Deterministic") results were obtained in 24 minutes. In general, deterministic approaches tend to be more efficient than brute-force Monte Carlo.
-
+
One situation in which you may need to perform brute-force Monte Carlo simulations is that of nonlinear or time-varying media, because the equivalence between random and deterministic simulations above relied on linearity and time-invariance. However, in such media one also cannot directly employ white-noise sources, but you must instead input the noise with the correct spectrum for your desired emission process. For example, to [model thermal emission in a nonlinear medium](http://doi.org/10.1103/PhysRevB.91.115406) one must have a noise spectrum consistent with the [fluctuation-dissipation theorem](https://en.wikipedia.org/wiki/Fluctuation-dissipation_theorem), which can be achieved using the `noisy-lorentzian-susceptibility` feature in Meep.
diff --git a/doc/docs/Scheme_Tutorials/Cylindrical_Coordinates.md b/doc/docs/Scheme_Tutorials/Cylindrical_Coordinates.md
index 5627116a5..cb4f185a9 100644
--- a/doc/docs/Scheme_Tutorials/Cylindrical_Coordinates.md
+++ b/doc/docs/Scheme_Tutorials/Cylindrical_Coordinates.md
@@ -117,13 +117,13 @@ Note that, because of the `to-appended` command, the `ring-cyl-ez.h5` file is a
$E_z$ for $\omega$=0.118 $m$=3 mode:
-
+
$E_z$ for $\omega$=0.148 $m$=4 mode:
-
+
$E_z$ for $\omega$=0.176 $m$=5 mode:
-
+
Because only the $\phi$=0 slice is used, the visual distinction between $m$ values is much less than with the 2d simulation. What is apparent is that, as the frequency increases, the mode becomes more localized in the waveguide and the radiating field (seen in the $r \times t$ slice as curved waves extending outward) becomes less, as expected.
@@ -426,7 +426,7 @@ set(gca, "yminorgrid", "on");
As shown below, the results for the scattering cross section computed using cylindrical coordinates agree well with the 3d Cartesian simulation. However, there is a large discrepancy in performance: for a single Intel Xeon 4.2GHz processor, the runtime of the cylindrical simulation is nearly 90 times shorter than the 3d simulation.
-
+
Focusing Properties of a Binary-Phase Zone Plate
@@ -445,7 +445,7 @@ $$ r_n^2 = n\lambda (f+\frac{n\lambda}{4})$$
where $n$ is the zone index (1,2,3,...,$N$), $f$ is the focal length, and $\lambda$ is the operating wavelength. The main design variable is the number of zones $N$. The design specifications of the zone plate are similar to the binary-phase grating in [Tutorial/Mode Decomposition/Diffraction Spectrum of a Binary Grating](Mode_Decomposition.md#diffraction-spectrum-of-a-binary-grating) with refractive index of 1.5 (glass), $\lambda$ of 0.5 μm, and height of 0.5 μm. The focusing property of the zone plate is verified by the concentration of the electric-field energy density at the focal length of 0.2 mm (which lies *outside* the cell). The planewave is incident from within a glass substrate and spans the entire length of the cell in the radial direction. The cell is surrounded on all sides by PML. A schematic of the simulation geometry for a design with 25 zones and flat-surface termination is shown below. The near-field monitor is positioned at the edge of the PML and captures the scattered fields in *all* directions.
-
+
The simulation script is in [examples/zone-plate.ctl](https://github.com/NanoComp/meep/blob/master/scheme/examples/zone-plate.ctl).
@@ -550,4 +550,4 @@ set (gca, "yminorgrid", "on");
Shown below is the far-field energy-density profile around the focal length for both the *r* and *z* coordinate directions for three lens designs with $N$ of 25, 50, and 100. The focus becomes sharper with increasing $N$ due to the enhanced constructive interference of the diffracted beam. As the number of zones $N$ increases, the size of the focal spot (full width at half maximum) at $z = 200$ μm decreases as $1/\sqrt{N}$ (see eq. 17 of the [reference](http://zoneplate.lbl.gov/theory)). This means that doubling the resolution (halving the spot width) requires quadrupling the number of zones.
-
+
diff --git a/doc/docs/Scheme_Tutorials/Eigenmode_Source.md b/doc/docs/Scheme_Tutorials/Eigenmode_Source.md
index b4d104483..80fea7739 100644
--- a/doc/docs/Scheme_Tutorials/Eigenmode_Source.md
+++ b/doc/docs/Scheme_Tutorials/Eigenmode_Source.md
@@ -12,7 +12,7 @@ Index-Guided Modes in a Ridge Waveguide
The first structure, shown in the schematic below, is a 2d ridge waveguide with ε=12, width $a$=1 μm, and out-of-plane electric field Ez. The dispersion relation ω(k) for index-guided modes with *even* mirror symmetry in the $y$-direction is computed using [MPB](https://mpb.readthedocs.io/en/latest/) and shown as blue lines. The light cone which denotes radiative modes is the section in solid green. Using this waveguide configuration, we will investigate two different frequency regimes: (1) single mode (normalized frequency of 0.15) and (2) multi mode (normalized frequency of 0.35), both shown as dotted horizontal lines in the figures. We will use the eigenmode source to excite a specific mode in each case — labeled **A** and **B** in the band diagram — and compare the results to using a constant-amplitude source for straight and rotated waveguides. Finally, we will demonstrate that a single monitor plane in the $y$-direction is sufficient for computing the total Poynting flux in a waveguide with any arbitrary orientation.
-
+
The simulation script is in [examples/oblique-source.ctl](https://github.com/NanoComp/meep/blob/master/scheme/examples/oblique-source.ctl).
@@ -185,15 +185,15 @@ axis tight;
```
-
+
-
+
-
+
These results demonstrate that in all cases the error is nearly 0 at the center frequency and increases roughly quadratically away from the center frequency. The error tends to be smallest for single-mode waveguides because a localized source excitation couples most strongly into guided modes. Note that in this case the maximum error is ~1% for a source bandwidth that is 67% of its center frequency. For the multi-mode waveguide, a much larger scattering loss is obtained for the higher-order mode **A** at frequencies below the center frequency, but this is simply because that mode ceases to be guided around a frequency `≈ 0.3`, and the mode pattern changes dramatically as this cutoff is approached.
@@ -207,13 +207,13 @@ The eigenmode source can also be used to launch modes in an oblique/rotated wave
Note that an oblique waveguide leads to a breakdown in the [PML](../Perfectly_Matched_Layer.md#breakdown-of-pml-in-inhomogeneous-media). A simple workaround for mitigating the PML reflection artifacts in this case is to double the `thickness` from 1 to 2.
-
+
There are numerical dispersion artifacts due to the FDTD spatial and temporal discretizations which create negligible backward-propagating waves by the eigenmode current source, carrying approximately 10-5 of the power of the desired forward-propagating mode. These artifacts can be seen as residues in the field profiles.
-
+
We demonstrate that the total power in a waveguide with *arbitrary* orientation — computed using two equivalent methods via `get_fluxes` and [mode decomposition](../Mode_Decomposition.md) — can be computed by a single flux plane oriented along the $y$ direction: thanks to [Poynting's theorem](https://en.wikipedia.org/wiki/Poynting%27s_theorem), the flux through any plane crossing a lossless waveguide is the same, regardless of whether the plane is oriented perpendicular to the waveguide. Furthermore, the eigenmode source is normalized in such a way as to produce the same power regardless of the waveguide orientation — in consequence, the flux values for mode **A** of the single-mode case for rotation angles of 0°, 20°, and 40° are 1111.280794, 1109.565028, and 1108.759159, within 0.2% (discretization error) of one another.
@@ -221,13 +221,13 @@ We demonstrate that the total power in a waveguide with *arbitrary* orientation
Finally, we demonstrate that as long as the line source intersects the waveguide *and* `eig-kpoint` is not nearly parallel to the direction of the line source, the mode can be properly launched. As shown in the field profiles below for the single-mode waveguide, there does not seem to be any noticeable distortion in the launched mode as the waveguide approaches glancing incidence to the source plane up to 80°, where the total power in the forward-propagating mode is 97%. Note that the line source spans the entire length of the cell extending into the PML region (not shown). In this example where the cell length is 10 μm (or 10X the width of the waveguide), the maximum rotation angle is ~84°, where the power drops to 59% and backward-propagating fields are clearly visible.
-
+
Increasing the size of the cell improves results at the expense of a larger simulation. The field profiles shown below are for a cell where the length has been doubled to 20 μm. The waveguide power at 84° increases from 59% to 80%. However, as the waveguide mode approaches glancing incidence, sensitivity to discretization errors increases because the mode varies rapidly with frequency on a glancing-angle cross-section, and you will eventually need to increase the resolution as well as the cell size. For waveguide angles much beyond 45° you probably want to simply change the orientation of the line source by 90°.
-
+
Planewaves in Homogeneous Media
@@ -279,4 +279,4 @@ Note that the line source spans the *entire* length of the cell. (Planewave sour
Shown below are the steady-state field profiles generated by the planewave for the three rotation angles. Residues of the backward-propagating waves due to the discretization are slightly visible.
-
+
diff --git a/doc/docs/Scheme_Tutorials/Frequency_Domain_Solver.md b/doc/docs/Scheme_Tutorials/Frequency_Domain_Solver.md
index 26bded54d..ac67e46ef 100644
--- a/doc/docs/Scheme_Tutorials/Frequency_Domain_Solver.md
+++ b/doc/docs/Scheme_Tutorials/Frequency_Domain_Solver.md
@@ -66,4 +66,4 @@ The simulation script is in [examples/solve-cw.ctl](https://github.com/NanoComp/
The results are shown in the figure below. The field profile is generated using [h5utils](https://github.com/NanoComp/h5utils/blob/master/README.md): `h5topng -o ring_field_profile.png -vZc bluered -C solve-cw-eps-000000.00.h5 solve-cw-ez-real-000000.00.h5`. The error in the fields decreases monotonically with decreasing tolerance of the frequency-domain solver. The error is converging to an asymptotic limit of `1e-12` which is set by the lowest tolerance. The inset shows the real part of the scalar Ez field, computed using a tolerance of `1e-12`, superimposed on the ring-resonator geometry. Note the three-fold mirror symmetry of the field pattern (fundamental mode) and the faint presence of the point source.
-
+
diff --git a/doc/docs/Scheme_Tutorials/Gyrotropic_Media.md b/doc/docs/Scheme_Tutorials/Gyrotropic_Media.md
index 3750812af..cbb2a36a0 100644
--- a/doc/docs/Scheme_Tutorials/Gyrotropic_Media.md
+++ b/doc/docs/Scheme_Tutorials/Gyrotropic_Media.md
@@ -74,7 +74,7 @@ The simulation cell is one pixel wide in the *x* and *y* directions, with period
After running the simulation, the `ex` and `ey` datasets in `faraday-rotation-efields.h5` contain the values of $\mathbf{E}_x$ and $\mathbf{E}_y$. These are plotted against *z* in the figure below:
-
+
We see that the wave indeed rotates in the *x*-*y* plane as it travels.
@@ -86,4 +86,4 @@ $$\epsilon_\perp = \epsilon_\infty + \frac{\omega_n^2 \Delta_n}{\Delta_n^2 - \om
From these expressions, we can calculate the rotation rate $\kappa_c$ at the operating frequency, and hence find the $\mathbf{E}_x$ and $\mathbf{E}_y$ field envelopes for the complex ansatz given at the top of this section. As shown in the figure below, the results are in excellent agreement:
-
+
diff --git a/doc/docs/Scheme_Tutorials/Local_Density_of_States.md b/doc/docs/Scheme_Tutorials/Local_Density_of_States.md
index 916a7bacc..359379914 100644
--- a/doc/docs/Scheme_Tutorials/Local_Density_of_States.md
+++ b/doc/docs/Scheme_Tutorials/Local_Density_of_States.md
@@ -84,4 +84,4 @@ We need to run for a sufficiently long time to ensure that the Fourier-transform
We run several simulations spanning a number of different notch sizes and plot the result in the following figure which shows good agreement between the two methods.
-
+
diff --git a/doc/docs/Scheme_Tutorials/Material_Dispersion.md b/doc/docs/Scheme_Tutorials/Material_Dispersion.md
index 9fbcf539c..17d4e7d60 100644
--- a/doc/docs/Scheme_Tutorials/Material_Dispersion.md
+++ b/doc/docs/Scheme_Tutorials/Material_Dispersion.md
@@ -88,7 +88,7 @@ legend("meep","analytic");
```
-
+
### Permittivity Function of an Artificial Dispersive Material
@@ -126,7 +126,7 @@ $$\varepsilon(\omega) = \varepsilon(2\pi f) = 2.25 + \frac{1.1^2 \cdot 0.5}{1.1^
The real and imaginary parts of this dielectric function ε(ω) are plotted below:
-
+
We can see that the f=1.1 resonance causes a large change in both the real and imaginary parts of ε around that frequency. In fact, there is a range of frequencies from 1.1 to 1.2161 where ε is *negative*. In this range, no propagating modes exist — it is actually a kind of electromagnetic band gap associated with polariton resonances in a material. For more information on the physics of such materials, see e.g. Chapter 14 of [Introduction to Solid State Physics](http://www.wiley.com/WileyCDA/WileyTitle/productCd-EHEP000803.html) by C. Kittel.
@@ -168,7 +168,7 @@ unix% meep material-dispersion.ctl | tee material-dispersion.out
we can then `grep` for the frequencies and the computed dielectric function, and plot it. First, let's plot the dispersion relation ω(k) for the real part of ω:
-
+
The red circles are the computed points from Meep, whereas the blue line is the analytical band diagram from the specified ε(ω). As you can see, we get *two* bands at each *k*, separated by a polaritonic gap (shaded yellow). This dispersion relation can be thought of as the interaction (anti-crossing) between the light line of the ambient ε=2.25 material (dashed black line) and the horizontal line corresponding to the phonon resonance.
@@ -176,13 +176,13 @@ The red circles are the computed points from Meep, whereas the blue line is the
Similarly, the computed and analytical real parts of the dielectric function are given by:
-
+
which shows excellent agreement between the analytical (blue line) and numerical (red circles) calculations. The imaginary part, however, is more subtle:
-
+
The blue line is the analytical calculation from above and the red circles are the numerical value from Meep — why is the agreement so poor? There is nothing wrong with Meep, and this is *not* a numerical error. The problem is simply that we are comparing apples and oranges.
diff --git a/doc/docs/Scheme_Tutorials/Mode_Decomposition.md b/doc/docs/Scheme_Tutorials/Mode_Decomposition.md
index 36c2dbf53..1ac267633 100644
--- a/doc/docs/Scheme_Tutorials/Mode_Decomposition.md
+++ b/doc/docs/Scheme_Tutorials/Mode_Decomposition.md
@@ -12,7 +12,7 @@ Reflectance of a Waveguide Taper
This example involves computing the reflectance of the fundamental mode of a linear waveguide taper. The structure and the simulation parameters are shown in the schematic below. We will verify that computing the reflectance, the fraction of the incident power which is reflected, using two different methods produces nearly identical results: (1) mode decomposition and (2) [Poynting flux](../Introduction.md#transmittancereflectance-spectra). Also, we will demonstrate that the scaling of the reflectance with the taper length is quadratic, consistent with analytical results from [Optics Express, Vol. 16, pp. 11376-92, 2008](http://www.opticsinfobase.org/abstract.cfm?URI=oe-16-15-11376).
-
+
The structure, which can be viewed as a [two-port network](https://en.wikipedia.org/wiki/Two-port_network), consists of a single-mode waveguide of width 1 μm (`w1`) at a wavelength of 6.67 μm and coupled to a second waveguide of width 2 μm (`w2`) via a linearly-sloped taper of variable length `Lt`. The material is silicon with ε=12. The taper geometry is defined using a single [`prism`](../Scheme_User_Interface.md#prism) object with eight vertices. PML absorbing boundaries surround the entire cell. An eigenmode current source with $E_z$ polarization is used to launch the fundamental mode. The dispersion relation (or "band diagram") of the single-mode waveguide is shown in [Tutorial/Eigenmode Source](Eigenmode_Source.md). There is an eigenmode-expansion monitor placed at the midpoint of the first waveguide. This is a line monitor which extends beyond the waveguide in order to span the entire mode profile including its evanescent tails. The Fourier-transformed fields along this line monitor are used to compute the basis coefficients of the harmonic modes. These are computed separately via the eigenmode solver [MPB](https://mpb.readthedocs.io/en/latest/). This is described in [Mode Decomposition](../Mode_Decomposition.md) where it is also shown that the squared magnitude of the mode coefficient is equivalent to the power (Poynting flux) in the given eigenmode. The ratio of the complex mode coefficients can be used to compute the [S parameters](https://en.wikipedia.org/wiki/Scattering_parameters). In this example, we are computing |S11|2 which is the reflectance (shown in the lines prefixed by "refl:,"). Another line monitor could have been placed in the second waveguide to compute the transmittance or |S21|2 into the various guided modes (since the second waveguide is multi mode). The scattered power into the radiative modes can then be computed as 1-|S11|2-|S21|2. As usual, a normalization run is required involving a straight waveguide to compute the power in the source.
@@ -144,7 +144,7 @@ axis([0.9 20 1e-6 1e-2]);
```
-
+
The reflectance values computed using the two methods are nearly identical. For reference, a line with quadratic scaling is shown in black. The reflectance of the linear waveguide taper decreases quadratically with the taper length which is consistent with the analytic theory.
@@ -163,7 +163,7 @@ A pulsed planewave with $E_z$ polarization spanning wavelengths of 0.4 to 0.6 μ
The simulation script is in [examples/binary_grating.ctl](https://github.com/NanoComp/meep/blob/master/scheme/examples/binary_grating.ctl).
-
+
```scm
@@ -300,7 +300,7 @@ Each diffraction order corresponds to a single angle. In the figure below, this
The diffraction orders/modes are a finite set of propagating planewaves. The wavevector kx of these modes can be computed analytically: for a frequency of ω (in c=1 units), these propagating modes are the **real** solutions of sqrt(ω²n²-(ky+2πm/Λ)²) where m is the diffraction order (an integer), Λ is the periodicity of the grating, and n is the refractive index of the propagating medium. In this example, n=1, ky=0, and Λ=10 μm. Thus, at a wavelength of 0.5 μm there are a total of 20 diffraction orders of which we only computed the first 10. The wavevector kx is used to compute the angle of the diffraction order as cos-1(kx/(ωn)). Evanescent modes, those with an imaginary kx, exist for |m|>20 but these modes carry no power. Note that currently Meep does not compute the number of propagating modes for you. If the mode number passed to `get-eigenmode-coefficients` is larger than the number of propagating modes at a given frequency/wavelength, MPB's Newton solver will fail to converge and will return zero for the mode coefficient. It is therefore a good idea to know beforehand the number of propagating modes.
-
+
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π)2 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 at λ=0.5 μm. Note the wavelength dependence of the transmittance and, in particular, the slightly *non-zero* diffraction efficiency for the even orders at wavelengths other than 0.5 μm. 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.
@@ -310,7 +310,7 @@ To convert the diffraction efficiency into transmittance in the *x* direction (i
Finally, by investigating the transmittance of the zeroth order (at a wavelength of 0.5 μm) in the limit as the grating periodicity approaches zero, we can demonstrate the breakdown of the scalar theory in the wavelength-scale regime which can only be solved using a full-wave method. When the periodicity is much less than the wavelength (i.e., subwavelength), the transmittance can again be solved analytically using effective-medium theory involving a three-layer structure: a layer of the averaged ε (mean or harmonic mean depending on the polarization $E_z$ or Hz) sandwiched between the glass substrate and air. Results are shown in the following figure.
-
+
Starting around a grating periodicity of 1.0 μm, the transmittance is no longer zero and increases rapidly with decreasing periodicity. As shown in the inset, for periodicities less than 0.5 μm, the transmittance converges to its asymptotic limit determined by the effective-medium theory: 0.99744 for the $E_z$ and 0.99057 for the Hz polarization. The weak polarization dependence is due to the low index contrast. The oscillations in the data are real and *not* an artifact of the discretization. For example, note the "hump" in the transmittance spectra for the $E_z$ polarization near a grating periodicity of 1.0 μm (twice the wavelength). This feature is associated with a "Wood anomaly" (see e.g. [Hessel and Oliner, 1965](https://www.osapublishing.org/ao/abstract.cfm?uri=ao-4-10-1275)), which occurs when new diffracted orders appear in the far field; for normal incidence, new diffraction orders appear as the period goes through any multiple of the wavelength.
@@ -686,7 +686,7 @@ title("phase (radians)");
The figure below shows the transmittance spectra (left) and phase map (right). The transmittance is nearly unity over most of the parameter space mainly because of the subwavelength dimensions of the grating. The phase variation spans the full range of -π to +π at each wavelength but varies weakly with the duty cycle due to the relatively low index of the glass grating. Higher-index materials such as [titanium dioxide](https://en.wikipedia.org/wiki/Titanium_dioxide#Thin_films) (TiO2) generally provide more control over the phase.
-
+
See [Tutorials/Near to Far Field Spectra/Focusing Properties of a Metasurface Lens](Near_to_Far_Field_Spectra.md#focusing-properties-of-a-metasurface-lens) for a related example.
@@ -699,7 +699,7 @@ As a final demonstration of mode decomposition, we compute the diffraction spect
A schematic of the grating geometry is shown below. The grating is a 2d slab in the *xy*-plane with two parameters: birefringence (Δn) and thickness (d). The twisted-nematic grating consists of two layers of thickness d each with equal and opposite rotation angles of φ=70° for the nematic director. Both gratings contain only three diffraction orders: m=0, ±1. The m=0 order is linearly polarized and the m=±1 orders are circularly polarized with opposite chirality. For the uniaxial grating, the diffraction efficiencies for a mode with wavelength λ can be computed analytically: η0=cos2(πΔnd/λ), η±1=0.5sin2(πΔnd/λ). The derivation of these formulas is presented in [Optics Letters, Vol. 24, No. 9, pp. 584-6, 1999](https://www.osapublishing.org/ol/abstract.cfm?uri=ol-24-9-584). We will verify these analytic results and also demonstrate that the twisted-nematic grating produces a broader bandwidth response for the ±1 orders than the homogeneous uniaxial grating. An important property of these polarization gratings for e.g. display applications is that for a circular-polarized input planewave and phase delay (Δnd/λ) of nearly 0.5, there is only a single diffraction order (+1 or -1) with *opposite* chiraity to that of the input. This is also demonstrated below.
-
+
In this example, the input is a linear-polarized planewave pulse at normal incidence with center wavelength of λ=0.54 μm. The linear polarization is in the *yz*-plane with a rotation angle of 45° counter clockwise around the *x* axis. Two sets of mode coefficients are computed in the air region adjacent to the grating for each orthogonal polarization: `ODD-Z+EVEN-Y` and `EVEN-Z+ODD-Y`, which correspond to +ky + -ky (cosine) and +ky - -ky (sine) modes. From these coefficients for linear-polarized modes, the power in the circular-polarized modes can be computed: |ODD-Z+EVEN-Y|2+|EVEN-Z+ODD-Y|2. The power is identical for the two circular-polarized modes with opposite chiralities since the input is linearly polarized and at normal incidence. The transmittance for the diffraction orders are computed from the mode coefficients. As usual, this requires a separate normalization run to compute the power of the input planewave.
@@ -885,7 +885,7 @@ title("homogeneous uniaxial grating");
```
-
+
The left figure shows good agreement between the simulation results and analytic theory for the homogeneous uniaxial grating. Approximately 6% of the power in the input planewave is lost due to reflection from the grating. This value is an average over all phase delays. The total transmittance is therefore around 94%. The twisted-nematic grating, with results shown in the right figure, produces ±1 diffraction orders with nearly-constant peak transmittance over a broader bandwidth around Δnd/λ=0.5 than the homogeneous uniaxial polarization grating. This is consistent with results from the reference. The average reflectance and transmittance for the twisted-nematic grating are similar to those for the homogeneous uniaxial grating.
@@ -911,4 +911,4 @@ Note: when imparting a phase offset using a complex `amplitude`, it is *not* nec
The figure below shows a snapshot of $E_z$ within the cell for four different cases: phase delays (Δnd/λ) of 0.5 and 1.0, and planewave circular polarization of $E_z$+i$E_y$ and $E_z$-i$E_y$. The empty regions on the cell sides are PMLs. The thin solid black line denotes the boundary between the grating (on the left) and air. As expected, for Δnd/λ=0.5 there is just a single ±1 diffraction order which depends on the chirality of the input planewave (this is not the case for a linear-polarized planewave). The angle of this diffracted order (±4.8°) agrees with the analytic result. Snapshots of $E_y$ are similar.
-
+
diff --git a/doc/docs/Scheme_Tutorials/Multilevel_Atomic_Susceptibility.md b/doc/docs/Scheme_Tutorials/Multilevel_Atomic_Susceptibility.md
index 149e83051..81ed5cb6c 100644
--- a/doc/docs/Scheme_Tutorials/Multilevel_Atomic_Susceptibility.md
+++ b/doc/docs/Scheme_Tutorials/Multilevel_Atomic_Susceptibility.md
@@ -81,7 +81,7 @@ The field within the cavity is initialized to arbitrary non-zero values and a fi
The spectra of the field intensity is shown below.
-
+
There are two lasing modes above threshold in the vicinity of the center transition frequency ω$_a$=40 as we would expect. Remember, when finding the frequency axis that Meep uses a Courant factor of $\Delta t = 0.5 \Delta x$. We have also converted the electric field to SALT units using:
@@ -93,10 +93,10 @@ For two-level gain media, $\gamma_\parallel = \gamma_{12} + \gamma_{21}$. We can
By varying $N_0$ or the pumping rate $R_p$, we can change the total gain available in the cavity. This is used to find the laser's modal intensities as a function of the strength of the gain. We can compare the simulated modal intensity with SALT as well as an independent FDTD solver based on the Maxwell-Bloch equations. All three methods produce results with good agreement close to the first lasing threshold.
-
+
Further increasing the gain continues to yield good agreement.
-
+
diff --git a/doc/docs/Scheme_Tutorials/Near_to_Far_Field_Spectra.md b/doc/docs/Scheme_Tutorials/Near_to_Far_Field_Spectra.md
index b5a49194c..559b2f6ab 100644
--- a/doc/docs/Scheme_Tutorials/Near_to_Far_Field_Spectra.md
+++ b/doc/docs/Scheme_Tutorials/Near_to_Far_Field_Spectra.md
@@ -14,7 +14,7 @@ In this example, we compute the [radiation pattern](https://en.wikipedia.org/wik
The simulation geometry is shown in the following schematic.
-
+
In the first part of the simulation, we define the cell and source as well as the near field and flux regions. Since we are using a pulsed source (with center wavelength of 1 μm), the fields are timestepped until they have sufficiently decayed away.
@@ -137,7 +137,7 @@ set(gca, 'xtick', [0 0.5 1.0]);
```
-
+
@@ -337,7 +337,7 @@ grid on;
The phasemap is shown below. The left figure shows the transmittance which is nearly unity for all values of the duty cycle; the Fresnel transmittance is 0.96 for the glass-air interface. This is expected since the periodicity is subwavelength. The right figure shows the phase. There is a subregion in the middle of the plot spanning the duty-cycle range of roughly 0.16 to 0.65 in which the phase varies continuously over the full range of -2π to 0. This structural regime is used to design the supercell lens.
-
+
In the second part of the calculation, the far-field energy-density profile of three supercell lens designs, comprised of 201, 401, and 801 unit cells, are computed using the quadratic formula for the local phase. Initially, this involves fitting the unit-cell phase data to a finer duty-cycle grid in order to enhance the local-phase interpolation of the supercell. This is important since as the number of unit cells in the lens increases, the local phase via the duty cycle varies more gradually from unit cell to unit cell. However, if the duty cycle becomes too gradual (i.e., less than a tenth of the pixel dimensions), the `resolution` may also need to be increased in order to improve the accuracy of [subpixel smoothing](../Subpixel_Smoothing.md).
@@ -390,13 +390,13 @@ eval(sprintf("legend(\"num-cells = %d\",\"num-cells = %d\",\"num-cells = %d\")",
Shown below is the supercell lens design involving 201 unit cells. Note that even though periodic boundaries are used in the supercell calculation (via the `k-point`), the choice of cell boundaries in the *y* (or longitudinal) direction is *irrelevant* given the finite length of the lens. For example, PMLs could also have been used (at the expense of a larger cell). Although [`add-near2far`](../Scheme_User_Interface.md#near-to-far-field-spectra) does support periodic boundaries (via the `nperiods` parameter), it is not necessary for this particular example.
-
+
The far-field energy-density profile is shown below for the three lens designs. As the number of unit cells increases, the focal spot becomes sharper and sharper. This is expected since the longer the focal length, the bigger the lens required to demonstrate focusing (which means more unit cells). In this example, the largest lens design contains 801 unit cells which corresponds to 0.24 mm or 1.2X the focal length.
-
+
Diffraction Spectrum of a Finite Binary Grating
@@ -581,7 +581,7 @@ eval(sprintf("title(\"f.-f. spectra @ %0.1f um\")",wvl_slice));
```
-
+
For the case of `nperiods = 1`, three diffraction orders are present in the far-field spectra as broad peaks with finite angular width (a fourth peak/order is also visible). When `nperiods = 10`, the diffraction orders become sharp, narrow peaks. The three diffraction orders are labeled in the right inset of the bottom figure as m=1, 3, and 5 corresponding to angles 2.9°, 8.6°, and 14.5° which, along with the diffraction efficiency, can be computed analytically using scalar theory as described in [Tutorial/Mode Decomposition/Diffraction Spectrum of a Binary Grating](Mode_Decomposition.md#diffraction-spectrum-of-a-binary-grating). As an additional validation of the simulation results, the ratio of any two diffraction peaks pa/pb (a,b = 1,3,5,...) is consistent with that of its diffraction efficiencies: b2/a2.
@@ -595,7 +595,7 @@ Finally, we can validate the results for the diffraction spectra of a finite gra
The simulation setup is shown in the schematic below. The binary grating has Λ = 1 μm at a wavelength of 0.5 μm via a normally-incident planewave pulse (which must [extend into the PML region in order to span the entire width of the cell](../Perfectly_Matched_Layer.md#planewave-sources-extending-into-pml)). The grating structure is terminated with a flat-surface padding in order to give the scattered field space to decay at the edge of the cell.
-
+
The simulation script is in [examples/finite_grating.ctl](https://github.com/NanoComp/meep/blob/master/scheme/examples/finite_grating.ctl).
@@ -743,11 +743,11 @@ endif
```
-
+
-
+
The scattered field amplitude profile (the top figure in each of the two sets of results) shows that the fields decay to zero away from the grating (which is positioned at the left edge of the figure in the region indicated by the bright spots). The middle figure is the field amplitude along a 1d slice above the grating (marked by the dotted green line in the top figure). Note the decaying fields at the edges due to the flat-surface termination. The bottom figure is the Fourier transform of the fields from the 1d slice. As expected, there are only three diffraction orders present at ky=2πm/Λ for m=0, ±1, ±2. These peaks are becoming sharper as the number of grating periods increases.
@@ -761,7 +761,7 @@ Far-Field Profile of a Cavity
For this demonstration, we will compute the far-field spectra of a resonant cavity mode in a holey waveguide; a structure we had explored in [Tutorial/Resonant Modes and Transmission in a Waveguide Cavity](Resonant_Modes_and_Transmission_in_a_Waveguide_Cavity.md). The script is in [examples/cavity-farfield.ctl](https://github.com/NanoComp/meep/blob/master/scheme/examples/cavity-farfield.ctl). The structure is shown at the bottom of the left image below.
-
+
To set this up, we simply remove the last portion of [examples/holey-wvg-cavity.ctl](https://github.com/NanoComp/meep/blob/master/scheme/examples/holey-wvg-cavity.ctl), beginning right after the line:
diff --git a/doc/docs/Scheme_Tutorials/Optical_Forces.md b/doc/docs/Scheme_Tutorials/Optical_Forces.md
index ee180f93b..06626e7a0 100644
--- a/doc/docs/Scheme_Tutorials/Optical_Forces.md
+++ b/doc/docs/Scheme_Tutorials/Optical_Forces.md
@@ -5,7 +5,7 @@
This tutorial demonstrates Meep's ability to compute classical forces via the [Maxwell stress tensor](https://en.wikipedia.org/wiki/Maxwell_stress_tensor). The geometry consists of two identical, parallel, silicon waveguides with square cross section in vacuum. A schematic of the geometry is shown below. Due to the parallel orientation of the waveguides (propagation axis along $z$ and separation in $x$), the two modes can be chosen to be either symmetric or anti-symmetric with respect to an $x$ mirror-symmetry plane between them. As the two waveguides are brought closer and closer together, their modes couple and give rise to a gradient force that is *transverse* to the waveguide axis (i.e., in the $x$ direction). This is different from [radiation pressure](https://en.wikipedia.org/wiki/Radiation_pressure) which involves momentum exchange between photons and is longitudinal in nature (i.e., along the $z$ direction). An interesting phenomena that occurs for this coupled waveguide system is that the force can be tuned to be either attractive or repulsive depending on the relative phase of the two modes. This tutorial will demonstrate this effect.
-
+
The gradient force $F$ on each waveguide arising from the evanescent coupling of the two waveguide modes can be computed analytically:
@@ -116,7 +116,7 @@ The simulation is run over the range of separation distances $s$ from 0.05 to 1.
The following figure shows the $E_y$ mode profiles at a waveguide separation distance of 0.1 μm. This figure shows the source and flux monitor (red hatches), force monitors (blue lines), and PMLs (green hatches) surrounding the cell. From the force spectra shown above, at this separation distance the anti-symmetric mode is repulsive whereas the symmetric mode is attractive.
-
+
The MPB simulation is in [examples/parallel-wvgs-mpb.ctl](https://github.com/NanoComp/meep/blob/master/scheme/examples/parallel-wvgs-mpb.ctl). There are important differences related to the coordinate dimensions between the MPB and Meep scripts. In the MPB script, the 2d cell is defined using the $yz$ plane, the waveguide propagation axis is $x$, and the waveguide separation axis is $y$. As a consequence, the `num-bands` parameter is always `1` since the $y$ parity of the mode can be defined explicitly (i.e., `run-yodd-zodd` vs. `run-yeven-zodd`). This is different from the Meep script since Meep requires that a 2d cell be defined in the $xy$ plane. MPB has no such requirement.
diff --git a/doc/docs/Scheme_Tutorials/Resonant_Modes_and_Transmission_in_a_Waveguide_Cavity.md b/doc/docs/Scheme_Tutorials/Resonant_Modes_and_Transmission_in_a_Waveguide_Cavity.md
index 9c9d92e5e..0ffa5bc5d 100644
--- a/doc/docs/Scheme_Tutorials/Resonant_Modes_and_Transmission_in_a_Waveguide_Cavity.md
+++ b/doc/docs/Scheme_Tutorials/Resonant_Modes_and_Transmission_in_a_Waveguide_Cavity.md
@@ -5,7 +5,7 @@
In this example, we will consider the two-dimensional structure shown below, which is based on a system considered in Chapter 7 of [Photonic Crystals: Molding the Flow of Light (second edition)](http://ab-initio.mit.edu/book). In particular, there are three basic ideas behind this structure, which we briefly summarize.
-
+
First, by taking a dielectric wavgeuide and perforating it with a periodic sequence of holes, we form a kind of photonic crystal: there are still index-guided modes propagating losslessly down the periodic waveguide, but there is also a partial *photonic band gap*: a range of frequencies in which *no guided modes* exist.
@@ -137,9 +137,9 @@ unix% h5topng -Zc dkbluered holey-wvg-cavity-hz-slice.h5
```
-
+
-
+
The $H_z$ slice in which time = vertical is interesting, because we can see the pulse propagating to the right, bouncing off of the holes, and also exciting a resonant mode in the cavity that sits in the center for a long time as it starts slowly leaking to the right.
@@ -160,7 +160,7 @@ unix% grep flux1: holey-wvg-cavity0.out > flux0.dat
which we then import into our plotting program, divide the two fluxes, and get:
-
+
The band gap is clearly visible as the range of very low transmission, and in the middle of the band gap is a sharp peak corresponding to the resonant mode trapped in the defect. The inset enlarges this peak, and shows that we didn't use quite enough frequency points to capture the whole shape although we could fit to a Lorentzian if we wanted. At the edges of the band gaps, the transmission goes up in broad Fabry-Perot resonance peaks which we will examine in more detail below. There is also some high-frequency oscillation visible at the left of the plot, which is a numerical artifact due to our pulse not having enough amplitude in that range.
@@ -239,7 +239,7 @@ unix% convert holey-wvg-cavity-hz-*.png holey-wvg-cavity-hz.gif
```
-
+
The mode has a frequency of 0.235, just as we saw in the transmission spectrum, and a $Q$ of 373 which we could have also found by fitting the transmission spectrum. This lifetime $Q$ includes two independent decay channels: light can decay from the cavity into the waveguide with lifetime $Q_w$, or it can radiate from the cavity into the surrounding air with lifetime $Q_r$, where
@@ -255,7 +255,7 @@ unix% meep N=5 compute-mode?=true holey-wvg-cavity.ctl |grep harminv
```
-
+
The results, shown above, are exactly what we expected: at first, an exponential increase of $Q$ with `N`, and then a saturation at $Q_r \approx 8750$. However, when we look at the Harminv output for larger `N`, something strange happens — it starts to find *more modes*! For example, at `N=16`, the output is:
@@ -273,7 +273,7 @@ unix% meep sy=12 fcen=0.328227374843021 df=0.01 N=16 compute-mode?=true h
```
-
+
From the image, the field is clearly localized around the defect in the center as opposed to being spread out evenly in the crystal like a band-edge state would be. In the defect, the pattern is higher order than the previous mode. It has an extra pair of nodes in the $y$ direction.
@@ -284,7 +284,7 @@ Band Diagram
Finally, we consider a smaller, more abstract calculation that we really should have done first. In particular, we compute the **band diagram** of the infinite periodic waveguide by itself with no defects. The structure is shown below. This is very similar to the types of calculations that [MPB](https://mpb.readthedocs.io) performs, but with a different method that has its own strengths and weaknesses. By analyzing what solutions can propagate in the periodic structure, one gains fundamental insight into the aperiodic structures above.
-
+
Let us briefly review the problem. In a periodic system of this sort, the eigen-solutions can be expressed in the form of *Bloch modes*: a periodic *Bloch envelope* multiplied by a planewave $\exp[i(\mathbf{k}\cdot\mathbf{x}-ω t)]$, where **k** is the *Bloch wavevector*. We wish to find the *bands* $ω(\mathbf{k})$. In this case, there is only *one* direction of periodicity, so we only have one wavevector component $k_x$. Moreover, the solutions are periodic functions of this wavevector: for a unit-period structure, $k_x$ and $k_x+2\pi$ are redundant. Also, $k_x$ and $-k_x$ are redundant by time-reversal symmetry, so we only need to look for solutions in the *irreducible Brillouin zone* from $k_x=0$ to $k_x=\pi$.
@@ -366,7 +366,7 @@ unix% grep freqs-im: holey-wvg-bands.out > fim.dat
Plotting the real parts of ω, where the light cone ω > *ck* is shaded gray, we find:
-
+
The gray shaded region is the **light cone**, $ω > ck_x$, which is the region corresponding to modes that are extended in the air surrounding the waveguide. Below the light cone, we see several discrete *guided bands*, which must have field patterns localized to the vicinity of the waveguide. The imaginary part of ω for bands below the light cone is very small, due to either numerical error or the finite computational cell size. Some tiny portion of the guided mode overlaps the PML. Note the band gap between the first and second guided mode, from about 0.2 to 0.3.
@@ -386,7 +386,7 @@ It is usually a good idea to examine the field patterns for any modes that you a
+ $k_x=0.25$, $ω=0.2506$ light-cone (extended) mode
-    
+    
- From the top, the first two pictures show the first two guided bands underneath the light cone at $k_x=0.4$. Note that the second guided band is propagating to the *left*, which is due to its negative slope (note, however, that there is a corresponding right-propagating mode at $k_x=-0.4$). Note that they are strongly (exponentially) localized to the waveguide, as they should be.
diff --git a/doc/docs/Scheme_Tutorials/Third_Harmonic_Generation.md b/doc/docs/Scheme_Tutorials/Third_Harmonic_Generation.md
index 5c2fd9868..79419bb07 100644
--- a/doc/docs/Scheme_Tutorials/Third_Harmonic_Generation.md
+++ b/doc/docs/Scheme_Tutorials/Third_Harmonic_Generation.md
@@ -68,7 +68,7 @@ Finally, we'll run the sources, plus additional time for the field to decay at t
In a linear calculation, we normalize the transmission against some reference spectrum, but in this case there is no obvious normalization so we will just plot the raw data for several values of `k` (i.e. of χ$^{(3)}$):
-
+
For small values of χ$^{(3)}$, we see a peak from our source at ω=1/3 and another peak precisely at the third-harmonic frequency 3ω=1. As the χ$^{(3)}$ gets larger, frequency-mixing *within* the peaks causes them to broaden, and finally for χ$^{(3)}=1$ we start to see a noisy, broad-spectrum transmission due to the phenomenon of **modulation instability**. Notice also that at around $10^{-13}$ the data looks weird; this is probably due to our finite simulation time, imperfect absorbing boundaries, etcetera. We haven't attempted to analyze it in detail for this case.
@@ -107,7 +107,7 @@ harmonics:, 0, 1.0, 225.25726603587043, 5.026979706160964e-16
That is, the linear transmission is 225.25726603587043 at ω, so we'll divide by this value and plot the fractional transmission at ω and 3ω as a function of χ$^{(3)}$ on a log-log scale:
-
+
As can be shown from coupled-mode theory or, equivalently, follows from [Fermi's golden rule](https://en.wikipedia.org/wiki/Fermi's_golden_rule), the third-harmonic power must go as the *square* of χ$^{(3)}$ as long as the nonlinearity is weak (i.e. in the first Born approximation limit, where the ω source is not depleted significantly). This is precisely what we see on the above graph, where the slope of the black line indicates an exact quadratic dependence, for comparison. Once the nonlinearity gets strong enough, however, this approximation is no longer valid and the dependence is complicated.
diff --git a/doc/docs/Subpixel_Smoothing.md b/doc/docs/Subpixel_Smoothing.md
index f6751513f..b3d2d25ec 100644
--- a/doc/docs/Subpixel_Smoothing.md
+++ b/doc/docs/Subpixel_Smoothing.md
@@ -5,7 +5,7 @@
Meep uses a [second-order accurate finite-difference scheme](https://en.wikipedia.org/wiki/Finite_difference_method#Accuracy_and_order) for discretizing [Maxwell's equations](Introduction.md#maxwells-equations). This means that the results from Meep converge to the "exact" result from the non-discretized (i.e., continuous) system quadratically with the grid resolution $\Delta x$. However, this second-order error $\mathcal{O}(\Delta x^2)$ is generally spoiled to first-order error $\mathcal{O}(\Delta x)$ if the discretization involves a *discontinuous* material boundary. Moreover, directly discretizing a discontinuity in $\varepsilon$ or $\mu$ leads to "stairstepped" interfaces that can only be varied in discrete jumps of one voxel. Meep solves both of these problems by smoothing $\varepsilon$ and $\mu$: before discretizing, discontinuities are smoothed into continuous transitions over a distance of one voxel $\Delta x$, using a second-order accurate averaging procedure summarized [below](#smoothed-permittivity-tensor-via-perturbation-theory). Subpixel smoothing, illustrated in the following schematic, enables the discretized solution to converge as quickly as possible to the exact solution as the `resolution` increases.
-
+
However, subpixel smoothing has five limitations:
@@ -105,13 +105,13 @@ A plot of the resonant frequency versus the ring radius is shown below for subpi
This particular resonant mode has a [quality (Q) factor](https://en.wikipedia.org/wiki/Q_factor) of ~107 at a frequency of 0.25 and radius of 2.0 μm. This means that roughly 4x107 optical periods are required to accurately resolve the field decay due to the Fourier uncertainty relation. Instead, [`Harminv`](Python_User_Interface.md#harminv) can resolve the $Q$ using just ~1000 periods. This is nearly a four orders of magnitude reduction in the run time.
-
+
To compare the convergence rate of the discretization error, the following plot shows the error in the resonant frequency (relative to the "exact" result at a resolution of 300 voxels/μm) as a function of the grid resolution for a ring geometry with a fixed inner radius of 2.0 μm. The no-smoothing results have a linear error due to the stairstepped interface discontinuities. The subpixel-smoothing results have roughly second-order convergence.
-
+
Enabling Averaging for Material Function
@@ -193,7 +193,7 @@ geometry = [mp.Prism(vertices_outer, height=mp.inf, material=mp.Medium(index=n))
The following convergence plot shows the frequency for the resonant mode with $H_z$ polarization and $Q$ of ~107 as a function of resolution.
-
+
There are three important items to note. (1) The pixel grid and prism representations are each converging to a different frequency than the material function and cylinder. This is because in the limit of infinite resolution, they are *different* structures than the cylinders. (2) The material function is the same structure as the cylinder with no smoothing. In the limit of infinite resolution, the material function and cylinder converge to the same frequency. The only difference is the *rate* of convergence: the cylinder is second order (due to subpixel smoothing) whereas the material function is first order. See the convergence plot above (third figure from the top). (3) The non-interpolated pixel grid shows irregular convergence compared with the interpolated grid. This is expected because the non-interpolated grid is discontinuous but the interpolated grid is not. Also, because these are different structures the two pixel grids converge to different frequencies. To see this trend clearly requires reducing the "jumpiness" of the non-interpolated grid: the Meep resolution needs to be increased beyond 200 which is already ~3X the grid resolution.
@@ -266,7 +266,7 @@ geometry = [mp.Block(center=mp.Vector3(),
The plot of the resonant mode frequency with resolution is shown in the figure below. There are two items to note: (1) three structures — "no smoothing", "Gaussian blur", and Sigmoid smoothed with pixel-sized smoothing width (`dr = 1/resolution`) labeled "Sigmoid boundaries (width=1/resolution)" — are converging to the same frequency. This is expected because the smoothing radius/width is going to zero as the resolution approaches infinity and thus the two smoothed structures are converging to the same discontinuous structure. The effect of the smoothing has been to make the convergence more regular compared with no smoothing. The Sigmoid-smoothed structure has the slowest convergence rate of the three. (2) The Sigmoid-smoothed structure with constant smoothing width (`dr = 0.05`) labeled "Sigmoid boundaries (width=constant)" is converging to a different frequency than the other three structures because it is a different structure.
-
+
Finally, it is worth mentioning that a Gaussian blur (which provides only first-order accuracy) would probably be slower than doing the second-order accurate anisotropic smoothing using a [level set](https://en.wikipedia.org/wiki/Level_set) since the smoothing (e.g., via a Sigmoid function) as well as the normal vector can be computed analytically for the level set (see [\#1229](https://github.com/NanoComp/meep/issues/1229)).
diff --git a/doc/docs/Yee_Lattice.md b/doc/docs/Yee_Lattice.md
index 34864e30d..fd380130b 100644
--- a/doc/docs/Yee_Lattice.md
+++ b/doc/docs/Yee_Lattice.md
@@ -3,7 +3,7 @@
---
-
+
In order to discretize Maxwell's equations with [second-order accuracy](https://en.wikipedia.org/wiki/Finite_difference_method#Accuracy_and_order) for homogeneous regions where there are no discontinuous material boundaries, FDTD methods *store different field components for different grid locations*. This discretization is known as a **Yee lattice**.
@@ -25,7 +25,7 @@ $$(i+\frac{1}{2},j+\frac{1}{2},k+\frac{1}{2})-\frac{1}{2} \hat{\mathbf{e}}_\ell
In two dimensions, the arrangement is similar except that we set $\hat{\mathbf{e}}_3=0$. The 2d Yee lattice for the $H_z$-polarization ($\mathbf{E}$ in the $xy$ plane and $\mathbf{H}$ in the $z$ direction) is shown in the figure below.
-
+
The consequence of the Yee lattice is that, whenever you need to access field components, e.g. to find the energy density $(\mathbf{E}^* \cdot \mathbf{D} + |\mathbf{H}|^2)/2$ or the flux $\textrm{Re}\, \mathbf{E}^* \times \mathbf{H}$, then the components need to be **interpolated** to some common point in order to remain second-order accurate. Meep automatically does this [interpolation](Introduction.md#the-illusion-of-continuity) for you wherever necessary — in particular, whenever you compute [energy density](Python_User_Interface.md#energy-density-spectra) or [Poynting flux](Python_User_Interface.md#flux-spectra), or whenever you [output a field to a file](Python_User_Interface.md#output-functions), it is stored at the centers of each grid voxel: $(i+0.5,j+0.5,k+0.5)$.
diff --git a/doc/docs/css/extra.css b/doc/docs/css/extra.css
index b1a303040..939a8d522 100644
--- a/doc/docs/css/extra.css
+++ b/doc/docs/css/extra.css
@@ -56,7 +56,7 @@ pre code.python {
font-size: 70%;
}
-/* Align images in MarkDown without eTML or extensions - Method 2
+/* Align images in MarkDown without eTML or extensions
* https://msudol.com/how-to-align-images-in-markdown-without-html-or-extensions/
*/
img[src*='#left'] {
diff --git a/doc/docs/index.md b/doc/docs/index.md
index bd92d9650..3db38a52c 100644
--- a/doc/docs/index.md
+++ b/doc/docs/index.md
@@ -1,5 +1,5 @@
-
+
**Meep** is a free and open-source software package for [electromagnetics](https://en.wikipedia.org/wiki/Electromagnetism) simulation via the [finite-difference time-domain](https://en.wikipedia.org/wiki/Finite-difference_time-domain_method) (**FDTD**) method spanning a broad range of applications.