diff --git a/RCWA_1D_examples/1D_Grating_Gaylord_TE.py b/RCWA_1D_examples/1D_Grating_Gaylord_TE.py
index 33ba1b4..c4e01c7 100644
--- a/RCWA_1D_examples/1D_Grating_Gaylord_TE.py
+++ b/RCWA_1D_examples/1D_Grating_Gaylord_TE.py
@@ -237,6 +237,11 @@ def grating_fft(eps_r):
#print(np.linalg.cond(X@b)); #not well conditioned.
term = X@a@fbiX; # THIS IS SHITTILY CONDITIONED
+ # This is different from the paper which is X @ b @ a_i @ f @ X.
+ # k_I and k_II have positive sign in imaginary part and it's the opposite of the paper.
+ # And because of this, a and b are switched here so it works.
+ # To correct this, use conjugate() method to inverse the sign of the imaginary part.
+
# print((np.linalg.cond(X), np.linalg.cond(term)))
# print(np.linalg.cond(I+term)); #but this is EXTREMELY WELL CONDITIONED.
f = np.matmul(W, I+term);
diff --git a/RCWA_1D_examples/1D_Grating_Gaylord_TM.py b/RCWA_1D_examples/1D_Grating_Gaylord_TM.py
index 01ed827..72660dd 100644
--- a/RCWA_1D_examples/1D_Grating_Gaylord_TM.py
+++ b/RCWA_1D_examples/1D_Grating_Gaylord_TM.py
@@ -229,6 +229,11 @@ def grating_fft(eps_r):
b = ab[PQ:,:];
term = X @ a @ np.linalg.inv(b) @ X;
+ # This is different from the paper which is X @ b @ a_i @ f @ X.
+ # k_I and k_II have positive sign in imaginary part and it's the opposite of the paper.
+ # And because of this, a and b are switched here so it works.
+ # To correct this, use conjugate() method to inverse the sign of the imaginary part.
+
f = W @ (I+term);
g = V@(-I+term);
T = np.linalg.inv(np.matmul(j*Z_I, f) + g);
diff --git a/notebooks/RCWA/RCWA_derivation.ipynb b/notebooks/RCWA/RCWA_derivation.ipynb
index 7e6a2e6..4076fe7 100644
--- a/notebooks/RCWA/RCWA_derivation.ipynb
+++ b/notebooks/RCWA/RCWA_derivation.ipynb
@@ -8,7 +8,7 @@
"source": [
"# Note on the derivation of the reflection and transmission coefficents in\n",
"Formulation for stable and efficient implementation of the rigorous coupled-wave analysis of binary gratings\n",
- "M. G. Moharam, Eric B. Grann, Drew A. Pommet, and T. K. Gaylord \n",
+ "M. G. Moharam, Eric B. Grann, Drew A. Pommet, and T. K. Gaylord
\n",
"\n",
"The final step in this paper seems straightforward but is actually non-trivial to work out to get the final working RCWA code"
]
@@ -17,47 +17,46 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "We start with a system of four equations: \n",
- "\n",
- "$\\begin{bmatrix} \n",
- "\\delta_{i0} \\\\ \n",
- "jn_Icos(\\theta)\\delta_{i0} \\\\ \n",
- "\\end{bmatrix}$ + \n",
- "$\\begin{bmatrix} \n",
- "I \\\\ \n",
- "-jY_I \\\\ \n",
- "\\end{bmatrix}$[R] = \n",
- "$\\begin{bmatrix} \n",
- "W & WX\\\\ \n",
- "V & -VX \\\\ \n",
- "\\end{bmatrix}$$\\begin{bmatrix} \n",
- "c^{+} \\\\ \n",
- "c^{-} \\\\ \n",
- "\\end{bmatrix}$\n",
- "\n",
- "\n",
- "$\\begin{bmatrix} \n",
- "I \\\\ \n",
- "jY_{II} \\\\ \n",
- "\\end{bmatrix}$[T] = \n",
- "$\\begin{bmatrix} \n",
- "WX & W\\\\ \n",
- "VX & -V \\\\ \n",
- "\\end{bmatrix}$$\\begin{bmatrix} \n",
- "c^{+} \\\\ \n",
- "c^{-} \\\\ \n",
- "\\end{bmatrix}$\n",
+ "We start with a system of four equations:\n",
+ "\n",
+ "$\\begin{align*}\n",
+ "\\begin{bmatrix}\n",
+ "\\delta_{i0} \\\\ jn_Icos(\\theta)\\delta_{i0}\n",
+ "\\end{bmatrix} +\n",
+ "\\begin{bmatrix}\n",
+ "I \\\\\n",
+ "-jY_I\n",
+ "\\end{bmatrix}R &= \\begin{bmatrix}\n",
+ "W & WX \\\\\n",
+ "V & -VX\n",
+ "\\end{bmatrix}\n",
+ "\\begin{bmatrix}\n",
+ "c^{+} \\\\\n",
+ "c^{-} \\\\\n",
+ "\\end{bmatrix} \\\\\n",
+ "\\begin{bmatrix}\n",
+ "I \\\\\n",
+ "jY_{II} \\\\\n",
+ "\\end{bmatrix}T &=\n",
+ "\\begin{bmatrix}\n",
+ "WX & W \\\\\n",
+ "VX & -V \\\\\n",
+ "\\end{bmatrix}\n",
+ "\\begin{bmatrix}\n",
+ "c^{+} \\\\\n",
+ "c^{-} \\\\\n",
+ "\\end{bmatrix}\n",
+ "\\end{align*}$\n",
"\n",
"This is the original form written in the paper, but it is more transparent to write them out so you see all four equations\n",
"\n",
"$\n",
- "\\delta_{i0} + R = Wc^{+}+WXc^{-} \n",
- "$
$\n",
- "jn_{I}cos(\\theta) -jY_IR = Vc^{+}-VXc^{-} \n",
- "$
$\n",
- "T = WXc^{+} + Wc^{-}\n",
- "$
$\n",
- "jY_{II} = VXc^{+} - Vc^{-}\n",
+ "\\begin{align*}\n",
+ "\\delta_{i0} + R &= Wc^{+}+WXc^{-} &(1)\\\\\n",
+ "jn_{I}cos(\\theta) -jY_IR &= Vc^{+}-VXc^{-} &(2)\\\\\n",
+ "T &= WXc^{+} + Wc^{-} &(3)\\\\\n",
+ "jY_{II} &= VXc^{+} - Vc^{-} &(4)\n",
+ "\\end{align*}\n",
"$"
]
},
@@ -72,84 +71,93 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "First we solve for $c^{-}$
\n",
- "$\n",
- "c^{-} = W^{-1}(T-Xc^{+})\n",
- "$\n",
- "
Now we can solve $c^{+}$ using the expression above
\n",
- "$\n",
- "c^{+} = F^{-1}(jY_{II} + VW^{-1})T\n",
- "$\n",
- "
where the term $F$ is given by:
\n",
- "$\n",
- "F = V(I+W^{-1})X\n",
- "$\n",
- "
We can substitute this back into the expression for $c^{-}$
\n",
- "$\n",
- "c^{-} = W^{-1}\\bigg(I-XF^{-1}(iY_{II}+VW^{-1})\\bigg)T\n",
+ "First we rewrite (3) for $c^{-}$\n",
+ "\n",
+ "$c^{-} = W^{-1}(T-Xc^{+})$\n",
+ "\n",
+ "Now we can solve $c^{+}$ using the expression (3) and (4)\n",
+ "\n",
"$\n",
- "
\n",
- "We will call the expression inside the big parentheses $G$ to keep notation simple"
+ "\\begin{align*}\n",
+ "jY_{II}T &= VXC^+ -V(W^{-1}(T-WXC^+)) \\\\\n",
+ "jY_{II}T &= VXC^+ -VW^{-1}T+VW^{-1}WXC^+ \\\\\n",
+ "&=(VX+VX)c^+ -VW^{-1}T \\\\\n",
+ "2VXc^+ &= jY_{II}T + VW^{-1}T \\\\\n",
+ "c^+ &= 0.5X^{-1}V^{-1}(jY_{II}T + VW^{-1}T) \\\\\n",
+ "&= 0.5X^{-1}V^{-1}(jY_{II} + VW^{-1})T \\\\\n",
+ "&= 0.5X^{-1}(W^{-1} + jV^{-1}Y_{II})T \\\\\n",
+ "\\end{align*}\n",
+ "$"
]
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
- "#### Now we mark the steps that substitutes our expressions above into the reflection equations\n",
- "First we rewrite the two reflection equations:
\n",
- "$\n",
- "\\delta_{i0} + R = Wc^{+}+WXc^{-} \n",
- "$
$\n",
- "jn_{I}cos(\\theta) -jY_IR = Vc^{+}-VXc^{-} \n",
- "$
\n",
- "\n",
- "Now we begin substitution:
\n",
- "$\n",
- "\\delta_{i0} + R = W\\bigg[F^{-1}(iY_{II}+VW^{-1}) +XG \\bigg]T\n",
- "$
\n",
- "$\n",
- "jn_Icos(\\theta)\\delta_{i0} -jY_IR = V\\bigg[ F^{-1}(iY_{II}+VW^{-1}) - XG\\bigg]T\n",
- "$\n",
- "
Now we do two notation simplifications:
\n",
- "$\n",
- "A = F^{-1}(iY_{II}+VW^{-1}) +XG \n",
- "$
\n",
- "$\n",
- "B = F^{-1}(iY_{II}+VW^{-1}) - XG\n",
- "$\n"
- ]
+ "We can substitute this back into the expression for $c^{-}$
\n",
+ "$\n",
+ "\\begin{align*}\n",
+ "c^{-} &= W^{-1}\\bigg[T - WX\\big( 0.5X^{-1}V^{-1}(jY_{II}+VW^{-1})T\\big)\\bigg]\\\\\n",
+ "&= W^{-1}\\bigg[T - 0.5WV^{-1}(jY_{II}+VW^{-1})T\\bigg] \\\\\n",
+ "&= W^{-1}T - 0.5V^{-1}(jY_{II}+VW^{-1})T \\\\\n",
+ "&= W^{-1}T - 0.5(V^{-1}jY_{II}+W^{-1})T \\\\\n",
+ "&= 0.5W^{-1}T - 0.5V^{-1}jY_{II}T \\\\\n",
+ "&= 0.5(W^{-1} -jV^{-1}Y_{II})T\n",
+ "\\end{align*}\n",
+ "$"
+ ],
+ "metadata": {
+ "collapsed": false
+ }
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
- "Now we can finally solve for R:
\n",
- "$\n",
- "T = A^{-1}(\\delta_{i0} + R)\n",
+ "#### Now we mark the steps that substitutes our expressions above into the reflection equations\n",
+ "First we rewrite the two reflection equations:
\n",
"$\n",
- "
\n",
+ "\\begin{align*}\n",
+ "\\delta_{i0} + R &= Wc^{+}+WXc^{-} \\\\\n",
+ "jn_{I}cos(\\theta) -jY_IR &= Vc^{+}-VXc^{-}\n",
+ "\\end{align*}\n",
"$\n",
- "(jn_Icos(\\theta) - VBA^{-1})\\delta_{i0} = (jY_I + VBA^{-1})R\n",
- "$
\n",
+ "\n",
+ "Now we begin substitution:
\n",
"$\n",
- "R = \\frac{(jn_Icos(\\theta) - VBA^{-1})}{(jY_I + VBA^{-1})}\\delta_{i0} \n",
- "$ "
- ]
+ "\\begin{align*}\n",
+ "\\begin{matrix}\n",
+ "\\delta_{i0} + R = W\\bigg(0.5X^{-1}(W^{-1} +jV^{-1}Y_{II})T \\bigg)+WX\\bigg(0.5(W^{-1} -jV^{-1}Y_{II})T \\bigg) \\\\\n",
+ "jn_{I}cos(\\theta) -jY_IR = V\\bigg(0.5X^{-1}(W^{-1} +jV^{-1}Y_{II})T \\bigg)-VX\\bigg(0.5(W^{-1} -jV^{-1}Y_{II})T \\bigg) \\\\\n",
+ "\\vdots\n",
+ "\\end{matrix}\n",
+ "\\end{align*}\n",
+ "$"
+ ],
+ "metadata": {
+ "collapsed": false
+ }
},
{
"cell_type": "markdown",
- "metadata": {},
"source": [
- "At this point we are done, we can now backsubstitute our solution for R into T and then finally into $c^{+}$ and $c^{-}$\n",
+ "## This may be able to solve, but it's not the point of this paper.\n",
+ "The point is to remove $X^{-1}$ which may have numerical instability problem.\n",
"\n",
- "THIS METHOD FAILS: TOO MUCH ILL CONDITIONING"
- ]
+ "BTW, the code in this repo is implemented as the paper suggested(with minor difference)."
+ ],
+ "metadata": {
+ "collapsed": false,
+ "pycharm": {
+ "name": "#%% md\n"
+ }
+ }
},
{
"cell_type": "markdown",
"metadata": {
- "collapsed": true
+ "collapsed": true,
+ "pycharm": {
+ "name": "#%% md\n"
+ }
},
"source": [
"# Potential Failure Case in RCWA with Scattering Matrices\n",
@@ -180,7 +188,7 @@
"K_z = \\bigg( \\sqrt{k_0^2n - K_x^2 - K_y^2} \\bigg)^*\n",
"$\n",
"\n",
- "THE ISSUE: WE CAN ENGINEER SITUATIONS WHERE KZ IS SINGULAR
\n",
+ "THE ISSUE: WE CAN ENGINEER SITUATIONS WHERE KZ IS SINGULAR
\n",
"typically, for our gap media, we pick $n_g=1$\n",
"Additionally, we normalize by $k_0 = \\frac{2\\pi}{\\lambda_0}$\n",
"\n",
@@ -196,20 +204,11 @@
"\n",
"This problem is not just for gap media, but also if any of the layers or reflection/transmission regions have such properties...As a result, it isn't obvious to me that scattering matrix formalism is 'unconditionally stable'"
]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": []
}
],
"metadata": {
"kernelspec": {
- "display_name": "Python 3",
+ "display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
@@ -223,9 +222,9 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.6.3"
+ "version": "3.9.6"
}
},
"nbformat": 4,
"nbformat_minor": 1
-}
+}
\ No newline at end of file