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