Publish docs for local build
This commit is contained in:
parent
e7cd1f4d50
commit
693e3af8fa
9 changed files with 2042 additions and 817 deletions
|
|
@ -1345,58 +1345,63 @@ matrix equation (Ax=b) or eigenvalue problem.</p>
|
|||
<p>From the "Frequency domain" section of <code>meanas.fdmath</code>, we have</p>
|
||||
<div class="arithmatex">\[
|
||||
\begin{aligned}
|
||||
\tilde{E}_{l, \vec{r}} &= \tilde{E}_{\vec{r}} e^{-\imath \omega l \Delta_t} \\
|
||||
\tilde{H}_{l - \frac{1}{2}, \vec{r} + \frac{1}{2}} &= \tilde{H}_{\vec{r} + \frac{1}{2}} e^{-\imath \omega (l - \frac{1}{2}) \Delta_t} \\
|
||||
\tilde{J}_{l, \vec{r}} &= \tilde{J}_{\vec{r}} e^{-\imath \omega (l - \frac{1}{2}) \Delta_t} \\
|
||||
\tilde{M}_{l - \frac{1}{2}, \vec{r} + \frac{1}{2}} &= \tilde{M}_{\vec{r} + \frac{1}{2}} e^{-\imath \omega l \Delta_t} \\
|
||||
\tilde{E}_{l, \vec{r}} &= \tilde{E}_{\vec{r}} e^{-\imath \omega l \Delta_t} \\
|
||||
\tilde{H}_{l - \frac{1}{2}, \vec{r} + \frac{1}{2}} &= \tilde{H}_{\vec{r} + \frac{1}{2}} e^{-\imath \omega (l - \frac{1}{2}) \Delta_t} \\
|
||||
\tilde{J}_{l, \vec{r}} &= \tilde{J}_{\vec{r}} e^{-\imath \omega (l - \frac{1}{2}) \Delta_t} \\
|
||||
\tilde{M}_{l - \frac{1}{2}, \vec{r} + \frac{1}{2}} &= \tilde{M}_{\vec{r} + \frac{1}{2}} e^{-\imath \omega l \Delta_t} \\
|
||||
\hat{\nabla} \times (\mu^{-1}_{\vec{r} + \frac{1}{2}} \cdot \tilde{\nabla} \times \tilde{E}_{\vec{r}})
|
||||
-\Omega^2 \epsilon_{\vec{r}} \cdot \tilde{E}_{\vec{r}} &= -\imath \Omega \tilde{J}_{\vec{r}} e^{\imath \omega \Delta_t / 2} \\
|
||||
\Omega &= 2 \sin(\omega \Delta_t / 2) / \Delta_t
|
||||
-\Omega^2 \epsilon_{\vec{r}} \cdot \tilde{E}_{\vec{r}} &= -\imath \Omega \tilde{J}_{\vec{r}} e^{\imath \omega \Delta_t / 2} \\
|
||||
\Omega &= 2 \sin(\omega \Delta_t / 2) / \Delta_t
|
||||
\end{aligned}
|
||||
\]</div>
|
||||
|
||||
<p>resulting in</p>
|
||||
<div class="arithmatex">\[
|
||||
\begin{aligned}
|
||||
\tilde{\partial}_t &\Rightarrow -\imath \Omega e^{-\imath \omega \Delta_t / 2}\\
|
||||
\hat{\partial}_t &\Rightarrow -\imath \Omega e^{ \imath \omega \Delta_t / 2}\\
|
||||
\tilde{\partial}_t &\Rightarrow -\imath \Omega e^{-\imath \omega \Delta_t / 2}\\
|
||||
\hat{\partial}_t &\Rightarrow -\imath \Omega e^{ \imath \omega \Delta_t / 2}\\
|
||||
\end{aligned}
|
||||
\]</div>
|
||||
|
||||
<p>Maxwell's equations are then</p>
|
||||
<div class="arithmatex">\[
|
||||
\begin{aligned}
|
||||
\tilde{\nabla} \times \tilde{E}_{\vec{r}} &=
|
||||
\tilde{\nabla} \times \tilde{E}_{\vec{r}} &=
|
||||
\imath \Omega e^{-\imath \omega \Delta_t / 2} \hat{B}_{\vec{r} + \frac{1}{2}}
|
||||
- \hat{M}_{\vec{r} + \frac{1}{2}} \\
|
||||
\hat{\nabla} \times \hat{H}_{\vec{r} + \frac{1}{2}} &=
|
||||
\hat{\nabla} \times \hat{H}_{\vec{r} + \frac{1}{2}} &=
|
||||
-\imath \Omega e^{ \imath \omega \Delta_t / 2} \tilde{D}_{\vec{r}}
|
||||
+ \tilde{J}_{\vec{r}} \\
|
||||
\tilde{\nabla} \cdot \hat{B}_{\vec{r} + \frac{1}{2}} &= 0 \\
|
||||
\hat{\nabla} \cdot \tilde{D}_{\vec{r}} &= \rho_{\vec{r}}
|
||||
\tilde{\nabla} \cdot \hat{B}_{\vec{r} + \frac{1}{2}} &= 0 \\
|
||||
\hat{\nabla} \cdot \tilde{D}_{\vec{r}} &= \rho_{\vec{r}}
|
||||
\end{aligned}
|
||||
\]</div>
|
||||
|
||||
<p>With <span class="arithmatex">\(\Delta_t \to 0\)</span>, this simplifies to</p>
|
||||
<div class="arithmatex">\[
|
||||
\begin{aligned}
|
||||
\tilde{E}_{l, \vec{r}} &\to \tilde{E}_{\vec{r}} \\
|
||||
\tilde{H}_{l - \frac{1}{2}, \vec{r} + \frac{1}{2}} &\to \tilde{H}_{\vec{r} + \frac{1}{2}} \\
|
||||
\tilde{J}_{l, \vec{r}} &\to \tilde{J}_{\vec{r}} \\
|
||||
\tilde{M}_{l - \frac{1}{2}, \vec{r} + \frac{1}{2}} &\to \tilde{M}_{\vec{r} + \frac{1}{2}} \\
|
||||
\Omega &\to \omega \\
|
||||
\tilde{\partial}_t &\to -\imath \omega \\
|
||||
\hat{\partial}_t &\to -\imath \omega \\
|
||||
\tilde{E}_{l, \vec{r}} &\to \tilde{E}_{\vec{r}} \\
|
||||
\tilde{H}_{l - \frac{1}{2}, \vec{r} + \frac{1}{2}} &\to \tilde{H}_{\vec{r} + \frac{1}{2}} \\
|
||||
\tilde{J}_{l, \vec{r}} &\to \tilde{J}_{\vec{r}} \\
|
||||
\tilde{M}_{l - \frac{1}{2}, \vec{r} + \frac{1}{2}} &\to \tilde{M}_{\vec{r} + \frac{1}{2}} \\
|
||||
\Omega &\to \omega \\
|
||||
\tilde{\partial}_t &\to -\imath \omega \\
|
||||
\hat{\partial}_t &\to -\imath \omega \\
|
||||
\end{aligned}
|
||||
\]</div>
|
||||
|
||||
<p>and then</p>
|
||||
<div class="arithmatex">\[
|
||||
\begin{aligned}
|
||||
\tilde{\nabla} \times \tilde{E}_{\vec{r}} &=
|
||||
\tilde{\nabla} \times \tilde{E}_{\vec{r}} &=
|
||||
\imath \omega \hat{B}_{\vec{r} + \frac{1}{2}}
|
||||
- \hat{M}_{\vec{r} + \frac{1}{2}} \\
|
||||
\hat{\nabla} \times \hat{H}_{\vec{r} + \frac{1}{2}} &=
|
||||
\hat{\nabla} \times \hat{H}_{\vec{r} + \frac{1}{2}} &=
|
||||
-\imath \omega \tilde{D}_{\vec{r}}
|
||||
+ \tilde{J}_{\vec{r}} \\
|
||||
\end{aligned}
|
||||
\]</div>
|
||||
|
||||
<div class="arithmatex">\[
|
||||
\hat{\nabla} \times (\mu^{-1}_{\vec{r} + \frac{1}{2}} \cdot \tilde{\nabla} \times \tilde{E}_{\vec{r}})
|
||||
-\omega^2 \epsilon_{\vec{r}} \cdot \tilde{E}_{\vec{r}} = -\imath \omega \tilde{J}_{\vec{r}} \\
|
||||
|
|
@ -2064,6 +2069,7 @@ mask selecting the total-field region, then the TFSF source is the commutator</p
|
|||
<div class="arithmatex">\[
|
||||
\frac{A Q - Q A}{-i \omega} E.
|
||||
\]</div>
|
||||
|
||||
<p>This vanishes in the interior of the total-field and scattered-field regions
|
||||
and is supported only at their shared boundary, where the mask discontinuity
|
||||
makes <code>A</code> and <code>Q</code> fail to commute. The returned current is therefore the
|
||||
|
|
@ -2416,11 +2422,15 @@ the <code>meanas.fdmath.types</code> submodule for details.</p>
|
|||
<div class="doc doc-contents ">
|
||||
|
||||
<p>Wave operator
|
||||
$$ \nabla \times (\frac{1}{\mu} \nabla \times) - \Omega^2 \epsilon $$</p>
|
||||
|
||||
<div class="arithmatex">\[ \nabla \times (\frac{1}{\mu} \nabla \times) - \Omega^2 \epsilon \]</div>
|
||||
</p>
|
||||
<div class="highlight"><pre><span></span><code>del x (1/mu * del x) - omega**2 * epsilon
|
||||
</code></pre></div>
|
||||
<p>for use with the E-field, with wave equation
|
||||
$$ (\nabla \times (\frac{1}{\mu} \nabla \times) - \Omega^2 \epsilon) E = -\imath \omega J $$</p>
|
||||
|
||||
<div class="arithmatex">\[ (\nabla \times (\frac{1}{\mu} \nabla \times) - \Omega^2 \epsilon) E = -\imath \omega J \]</div>
|
||||
</p>
|
||||
<div class="highlight"><pre><span></span><code>(del x (1/mu * del x) - omega**2 * epsilon) E = -i * omega * J
|
||||
</code></pre></div>
|
||||
<p>To make this matrix symmetric, use the preconditioners from <code>e_full_preconditioners()</code>.</p>
|
||||
|
|
@ -2678,11 +2688,15 @@ The PMC is applied per-field-component (i.e. <code>pmc.size == epsilon.size</cod
|
|||
<div class="doc doc-contents ">
|
||||
|
||||
<p>Wave operator
|
||||
$$ \nabla \times (\frac{1}{\epsilon} \nabla \times) - \omega^2 \mu $$</p>
|
||||
|
||||
<div class="arithmatex">\[ \nabla \times (\frac{1}{\epsilon} \nabla \times) - \omega^2 \mu \]</div>
|
||||
</p>
|
||||
<div class="highlight"><pre><span></span><code>del x (1/epsilon * del x) - omega**2 * mu
|
||||
</code></pre></div>
|
||||
<p>for use with the H-field, with wave equation
|
||||
$$ (\nabla \times (\frac{1}{\epsilon} \nabla \times) - \omega^2 \mu) E = \imath \omega M $$</p>
|
||||
|
||||
<div class="arithmatex">\[ (\nabla \times (\frac{1}{\epsilon} \nabla \times) - \omega^2 \mu) E = \imath \omega M \]</div>
|
||||
</p>
|
||||
<div class="highlight"><pre><span></span><code>(del x (1/epsilon * del x) - omega**2 * mu) E = i * omega * M
|
||||
</code></pre></div>
|
||||
|
||||
|
|
@ -2855,25 +2869,30 @@ The PMC is applied per-field-component (i.e. <code>pmc.size == epsilon.size</cod
|
|||
<div class="doc doc-contents ">
|
||||
|
||||
<p>Wave operator for <code>[E, H]</code> field representation. This operator implements Maxwell's
|
||||
equations without cancelling out either E or H. The operator is
|
||||
$$ \begin{bmatrix}
|
||||
-\imath \omega \epsilon & \nabla \times \
|
||||
\nabla \times & \imath \omega \mu
|
||||
\end{bmatrix} $$</p>
|
||||
equations without cancelling out either E or H. The operator is</p>
|
||||
<div class="arithmatex">\[
|
||||
\begin{bmatrix}
|
||||
-\imath \omega \epsilon & \nabla \times \\
|
||||
\nabla \times & \imath \omega \mu
|
||||
\end{bmatrix}
|
||||
\]</div>
|
||||
|
||||
<div class="highlight"><pre><span></span><code>[[-i * omega * epsilon, del x ],
|
||||
[del x, i * omega * mu]]
|
||||
</code></pre></div>
|
||||
<p>for use with a field vector of the form <code>cat(vec(E), vec(H))</code>:
|
||||
$$ \begin{bmatrix}
|
||||
-\imath \omega \epsilon & \nabla \times \
|
||||
\nabla \times & \imath \omega \mu
|
||||
<p>for use with a field vector of the form <code>cat(vec(E), vec(H))</code>:</p>
|
||||
<div class="arithmatex">\[
|
||||
\begin{bmatrix}
|
||||
-\imath \omega \epsilon & \nabla \times \\
|
||||
\nabla \times & \imath \omega \mu
|
||||
\end{bmatrix}
|
||||
\begin{bmatrix} E \
|
||||
\begin{bmatrix} E \\
|
||||
H
|
||||
\end{bmatrix}
|
||||
= \begin{bmatrix} J \
|
||||
= \begin{bmatrix} J \\
|
||||
-M
|
||||
\end{bmatrix} $$</p>
|
||||
\end{bmatrix}
|
||||
\]</div>
|
||||
|
||||
|
||||
<p><span class="doc-section-title">Parameters:</span></p>
|
||||
|
|
@ -3408,6 +3427,7 @@ usual antisymmetry of the cross product,</p>
|
|||
<div class="arithmatex">\[
|
||||
H \times E = -(E \times H),
|
||||
\]</div>
|
||||
|
||||
<p>once the same staggered field placement is used on both sides.</p>
|
||||
|
||||
|
||||
|
|
@ -3527,6 +3547,7 @@ Then the TFSF current operator is the commutator</p>
|
|||
<div class="arithmatex">\[
|
||||
\frac{A Q - Q A}{-i \omega}.
|
||||
\]</div>
|
||||
|
||||
<p>Inside regions where <code>Q</code> is locally constant, <code>A</code> and <code>Q</code> commute and the
|
||||
source vanishes. Only cells at the TF/SF boundary contribute nonzero current,
|
||||
which is exactly the desired distributed source for injecting the chosen
|
||||
|
|
|
|||
|
|
@ -1903,8 +1903,9 @@ series of other matrices).</p>
|
|||
which covers a superset of this material with similar notation and more detail.</p>
|
||||
<h4 id="meanas.fdmath--scalar-derivatives-and-cell-shifts">Scalar derivatives and cell shifts<a class="headerlink" href="#meanas.fdmath--scalar-derivatives-and-cell-shifts" title="Permanent link">¶</a></h4>
|
||||
<p>Define the discrete forward derivative as
|
||||
$$ [\tilde{\partial}<em _="+" _frac_1="\frac{1" m="m">x f]</em> - f_m) $$
|
||||
where }{2}} = \frac{1}{\Delta_{x, m}} (f_{m + 1<span class="arithmatex">\(f\)</span> is a function defined at discrete locations on the x-axis (labeled using <span class="arithmatex">\(m\)</span>).
|
||||
|
||||
<div class="arithmatex">\[ [\tilde{\partial}_x f]_{m + \frac{1}{2}} = \frac{1}{\Delta_{x, m}} (f_{m + 1} - f_m) \]</div></p>
|
||||
<p>where <span class="arithmatex">\(f\)</span> is a function defined at discrete locations on the x-axis (labeled using <span class="arithmatex">\(m\)</span>).
|
||||
The value at <span class="arithmatex">\(m\)</span> occupies a length <span class="arithmatex">\(\Delta_{x, m}\)</span> along the x-axis. Note that <span class="arithmatex">\(m\)</span>
|
||||
is an index along the x-axis, <em>not</em> necessarily an x-coordinate, since each length
|
||||
<span class="arithmatex">\(\Delta_{x, m}, \Delta_{x, m+1}, ...\)</span> is independently chosen.</p>
|
||||
|
|
@ -1913,8 +1914,9 @@ along the x-axis, the forward derivative is</p>
|
|||
<div class="highlight"><pre><span></span><code>deriv_forward(f)[i] = (f[i + 1] - f[i]) / dx[i]
|
||||
</code></pre></div>
|
||||
<p>Likewise, discrete reverse derivative is
|
||||
$$ [\hat{\partial}<em -="-" _frac_1="\frac{1" m="m">x f ]</em>) $$
|
||||
or}{2}} = \frac{1}{\Delta_{x, m}} (f_{m} - f_{m - 1</p>
|
||||
|
||||
<div class="arithmatex">\[ [\hat{\partial}_x f ]_{m - \frac{1}{2}} = \frac{1}{\Delta_{x, m}} (f_{m} - f_{m - 1}) \]</div></p>
|
||||
<p>or</p>
|
||||
<div class="highlight"><pre><span></span><code>deriv_back(f)[i] = (f[i] - f[i - 1]) / dx[i]
|
||||
</code></pre></div>
|
||||
<p>The derivatives' values are shifted by a half-cell relative to the original function, and
|
||||
|
|
@ -1949,7 +1951,9 @@ Periodic boundaries are used here and elsewhere unless otherwise noted.
|
|||
etc.</p>
|
||||
<p>The fractional subscript <span class="arithmatex">\(m + \frac{1}{2}\)</span> is used to indicate values defined
|
||||
at shifted locations relative to the original <span class="arithmatex">\(m\)</span>, with corresponding lengths
|
||||
$$ \Delta_{x, m + \frac{1}{2}} = \frac{1}{2} * (\Delta_{x, m} + \Delta_{x, m + 1}) $$</p>
|
||||
|
||||
<div class="arithmatex">\[ \Delta_{x, m + \frac{1}{2}} = \frac{1}{2} * (\Delta_{x, m} + \Delta_{x, m + 1}) \]</div>
|
||||
</p>
|
||||
<p>Just as <span class="arithmatex">\(m\)</span> is not itself an x-coordinate, neither is <span class="arithmatex">\(m + \frac{1}{2}\)</span>;
|
||||
carefully note the positions of the various cells in the above figure vs their labels.
|
||||
If the positions labeled with <span class="arithmatex">\(m\)</span> are considered the "base" or "original" grid,
|
||||
|
|
@ -1961,12 +1965,18 @@ See the <code>Grid description</code> section below for additional information o
|
|||
and generalization to three dimensions.</p>
|
||||
<h4 id="meanas.fdmath--gradients-and-fore-vectors">Gradients and fore-vectors<a class="headerlink" href="#meanas.fdmath--gradients-and-fore-vectors" title="Permanent link">¶</a></h4>
|
||||
<p>Expanding to three dimensions, we can define two gradients
|
||||
$$ [\tilde{\nabla} f]<em _="+" _frac_1="\frac{1" m="m">{m,n,p} = \vec{x} [\tilde{\partial}_x f]</em> +
|
||||
\vec{y} [\tilde{\partial}}{2},n,p<em _="+" _frac_1="\frac{1" m_n="m,n">y f]</em> +
|
||||
\vec{z} [\tilde{\partial}}{2},p<em _="+" _frac_1="\frac{1" m_n_p="m,n,p">z f]</em> $$
|
||||
$$ [\hat{\nabla} f]}{2}<em _="+" _frac_1="\frac{1" m="m">{m,n,p} = \vec{x} [\hat{\partial}_x f]</em> +
|
||||
\vec{y} [\hat{\partial}}{2},n,p<em _="+" _frac_1="\frac{1" m_n="m,n">y f]</em> +
|
||||
\vec{z} [\hat{\partial}}{2},p<em _="+" _frac_1="\frac{1" m_n_p="m,n,p">z f]</em> $$}{2}</p>
|
||||
<br />
|
||||
<div class="arithmatex">\[
|
||||
[\tilde{\nabla} f]_{m,n,p} = \vec{x} [\tilde{\partial}_x f]_{m + \frac{1}{2},n,p} +
|
||||
\vec{y} [\tilde{\partial}_y f]_{m,n + \frac{1}{2},p} +
|
||||
\vec{z} [\tilde{\partial}_z f]_{m,n,p + \frac{1}{2}}
|
||||
\]</div></p>
|
||||
<div class="arithmatex">\[
|
||||
[\hat{\nabla} f]_{m,n,p} = \vec{x} [\hat{\partial}_x f]_{m + \frac{1}{2},n,p} +
|
||||
\vec{y} [\hat{\partial}_y f]_{m,n + \frac{1}{2},p} +
|
||||
\vec{z} [\hat{\partial}_z f]_{m,n,p + \frac{1}{2}}
|
||||
\]</div>
|
||||
|
||||
<p>or</p>
|
||||
<div class="highlight"><pre><span></span><code>[code: gradients]
|
||||
grad_forward(f)[i,j,k] = [Dx_forward(f)[i, j, k],
|
||||
|
|
@ -1989,12 +1999,18 @@ at different points: the x-component is shifted in the x-direction,
|
|||
y in y, and z in z.</p>
|
||||
<p>We call the resulting object a "fore-vector" or "back-vector", depending
|
||||
on the direction of the shift. We write it as
|
||||
$$ \tilde{g}<em _="+" _frac_1="\frac{1" m="m">{m,n,p} = \vec{x} g^x</em> +
|
||||
<br />
|
||||
<div class="arithmatex">\[
|
||||
\tilde{g}_{m,n,p} = \vec{x} g^x_{m + \frac{1}{2},n,p} +
|
||||
\vec{y} g^y_{m,n + \frac{1}{2},p} +
|
||||
\vec{z} g^z_{m,n,p + \frac{1}{2}} $$
|
||||
$$ \hat{g}}{2},n,p<em -="-" _frac_1="\frac{1" m="m">{m,n,p} = \vec{x} g^x</em> +
|
||||
\vec{z} g^z_{m,n,p + \frac{1}{2}}
|
||||
\]</div></p>
|
||||
<div class="arithmatex">\[
|
||||
\hat{g}_{m,n,p} = \vec{x} g^x_{m - \frac{1}{2},n,p} +
|
||||
\vec{y} g^y_{m,n - \frac{1}{2},p} +
|
||||
\vec{z} g^z_{m,n,p - \frac{1}{2}} $$}{2},n,p</p>
|
||||
\vec{z} g^z_{m,n,p - \frac{1}{2}}
|
||||
\]</div>
|
||||
|
||||
<div class="highlight"><pre><span></span><code>[figure: gradient / fore-vector]
|
||||
(m, n+1, p+1) ______________ (m+1, n+1, p+1)
|
||||
/: /|
|
||||
|
|
@ -2010,14 +2026,20 @@ on the direction of the shift. We write it as
|
|||
</code></pre></div>
|
||||
<h4 id="meanas.fdmath--divergences">Divergences<a class="headerlink" href="#meanas.fdmath--divergences" title="Permanent link">¶</a></h4>
|
||||
<p>There are also two divergences,</p>
|
||||
<p>$$ d_{n,m,p} = [\tilde{\nabla} \cdot \hat{g}]<em m_n_p="m,n,p">{n,m,p}
|
||||
= [\tilde{\partial}_x g^x]</em> +
|
||||
[\tilde{\partial}<em m_n_p="m,n,p">y g^y]</em> +
|
||||
[\tilde{\partial}<em m_n_p="m,n,p">z g^z]</em> $$</p>
|
||||
<p>$$ d_{n,m,p} = [\hat{\nabla} \cdot \tilde{g}]<em m_n_p="m,n,p">{n,m,p}
|
||||
= [\hat{\partial}_x g^x]</em> +
|
||||
[\hat{\partial}<em m_n_p="m,n,p">y g^y]</em> +
|
||||
[\hat{\partial}<em m_n_p="m,n,p">z g^z]</em> $$</p>
|
||||
<div class="arithmatex">\[
|
||||
d_{n,m,p} = [\tilde{\nabla} \cdot \hat{g}]_{n,m,p}
|
||||
= [\tilde{\partial}_x g^x]_{m,n,p} +
|
||||
[\tilde{\partial}_y g^y]_{m,n,p} +
|
||||
[\tilde{\partial}_z g^z]_{m,n,p}
|
||||
\]</div>
|
||||
|
||||
<div class="arithmatex">\[
|
||||
d_{n,m,p} = [\hat{\nabla} \cdot \tilde{g}]_{n,m,p}
|
||||
= [\hat{\partial}_x g^x]_{m,n,p} +
|
||||
[\hat{\partial}_y g^y]_{m,n,p} +
|
||||
[\hat{\partial}_z g^z]_{m,n,p}
|
||||
\]</div>
|
||||
|
||||
<p>or</p>
|
||||
<div class="highlight"><pre><span></span><code>[code: divergences]
|
||||
div_forward(g)[i,j,k] = Dx_forward(gx)[i, j, k] +
|
||||
|
|
@ -2056,16 +2078,22 @@ is defined at the back-vector's (fore-vector's) location <span class="arithmatex
|
|||
</code></pre></div>
|
||||
<h4 id="meanas.fdmath--curls">Curls<a class="headerlink" href="#meanas.fdmath--curls" title="Permanent link">¶</a></h4>
|
||||
<p>The two curls are then</p>
|
||||
<p>$$ \begin{aligned}
|
||||
\hat{h}<em _="+" _frac_1="\frac{1" m="m">{m + \frac{1}{2}, n + \frac{1}{2}, p + \frac{1}{2}} &= \
|
||||
[\tilde{\nabla} \times \tilde{g}]</em> &=
|
||||
\vec{x} (\tilde{\partial}}{2}, n + \frac{1}{2}, p + \frac{1}{2}<em _="+" _frac_1="\frac{1" m_n_p="m,n,p">y g^z</em>}{2}} - \tilde{\partial<em _="+" _frac_1="\frac{1" m_n="m,n">z g^y</em>) \
|
||||
&+ \vec{y} (\tilde{\partial}}{2},p<em _="+" _frac_1="\frac{1" m="m">z g^x</em>}{2},n,p} - \tilde{\partial<em _="+" _frac_1="\frac{1" m_n_p="m,n,p">x g^z</em>) \
|
||||
&+ \vec{z} (\tilde{\partial}}{2}<em _="+" _frac_1="\frac{1" m_n="m,n">x g^y</em>}{2},p} - \tilde{\partial<em _="+" _frac_1="\frac{1" m="m">y g^z</em>)
|
||||
\end{aligned} $$}{2},n,p</p>
|
||||
<div class="arithmatex">\[
|
||||
\begin{aligned}
|
||||
\hat{h}_{m + \frac{1}{2}, n + \frac{1}{2}, p + \frac{1}{2}} &= \\
|
||||
[\tilde{\nabla} \times \tilde{g}]_{m + \frac{1}{2}, n + \frac{1}{2}, p + \frac{1}{2}} &=
|
||||
\vec{x} (\tilde{\partial}_y g^z_{m,n,p + \frac{1}{2}} - \tilde{\partial}_z g^y_{m,n + \frac{1}{2},p}) \\
|
||||
&+ \vec{y} (\tilde{\partial}_z g^x_{m + \frac{1}{2},n,p} - \tilde{\partial}_x g^z_{m,n,p + \frac{1}{2}}) \\
|
||||
&+ \vec{z} (\tilde{\partial}_x g^y_{m,n + \frac{1}{2},p} - \tilde{\partial}_y g^z_{m + \frac{1}{2},n,p})
|
||||
\end{aligned}
|
||||
\]</div>
|
||||
|
||||
<p>and</p>
|
||||
<p>$$ \tilde{h}<em -="-" _frac_1="\frac{1" m="m">{m - \frac{1}{2}, n - \frac{1}{2}, p - \frac{1}{2}} =
|
||||
[\hat{\nabla} \times \hat{g}]</em> $$}{2}, n - \frac{1}{2}, p - \frac{1}{2}</p>
|
||||
<div class="arithmatex">\[
|
||||
\tilde{h}_{m - \frac{1}{2}, n - \frac{1}{2}, p - \frac{1}{2}} =
|
||||
[\hat{\nabla} \times \hat{g}]_{m - \frac{1}{2}, n - \frac{1}{2}, p - \frac{1}{2}}
|
||||
\]</div>
|
||||
|
||||
<p>where <span class="arithmatex">\(\hat{g}\)</span> and <span class="arithmatex">\(\tilde{g}\)</span> are located at <span class="arithmatex">\((m,n,p)\)</span>
|
||||
with components at <span class="arithmatex">\((m \pm \frac{1}{2},n,p)\)</span> etc.,
|
||||
while <span class="arithmatex">\(\hat{h}\)</span> and <span class="arithmatex">\(\tilde{h}\)</span> are located at <span class="arithmatex">\((m \pm \frac{1}{2}, n \pm \frac{1}{2}, p \pm \frac{1}{2})\)</span>
|
||||
|
|
@ -2103,19 +2131,25 @@ curl_back(g)[i,j,k] = [Dy_back(gz)[i, j, k] - Dz_back(gy)[i, j, k],
|
|||
</code></pre></div>
|
||||
<h3 id="meanas.fdmath--maxwells-equations">Maxwell's Equations<a class="headerlink" href="#meanas.fdmath--maxwells-equations" title="Permanent link">¶</a></h3>
|
||||
<p>If we discretize both space (m,n,p) and time (l), Maxwell's equations become</p>
|
||||
<p>$$ \begin{aligned}
|
||||
\tilde{\nabla} \times \tilde{E}<em l-_frac_1="l-\frac{1">{l,\vec{r}} &= -\tilde{\partial}_t \hat{B}</em>
|
||||
- \hat{M}}{2}, \vec{r} + \frac{1}{2}<em l-_frac_1="l-\frac{1">{l, \vec{r} + \frac{1}{2}} \
|
||||
\hat{\nabla} \times \hat{H}</em>}{2},\vec{r} + \frac{1}{2}} &= \hat{\partial<em _vec_r="\vec{r" l_="l,">t \tilde{D}</em>
|
||||
+ \tilde{J}}<em l-_frac_1="l-\frac{1">{l-\frac{1}{2},\vec{r}} \
|
||||
\tilde{\nabla} \cdot \hat{B}</em> &= 0 \
|
||||
\hat{\nabla} \cdot \tilde{D}}{2}, \vec{r} + \frac{1}{2}<em l_vec_r="l,\vec{r">{l,\vec{r}} &= \rho</em>
|
||||
\end{aligned} $$}</p>
|
||||
<div class="arithmatex">\[
|
||||
\begin{aligned}
|
||||
\tilde{\nabla} \times \tilde{E}_{l,\vec{r}} &= -\tilde{\partial}_t \hat{B}_{l-\frac{1}{2}, \vec{r} + \frac{1}{2}}
|
||||
- \hat{M}_{l, \vec{r} + \frac{1}{2}} \\
|
||||
\hat{\nabla} \times \hat{H}_{l-\frac{1}{2},\vec{r} + \frac{1}{2}} &= \hat{\partial}_t \tilde{D}_{l, \vec{r}}
|
||||
+ \tilde{J}_{l-\frac{1}{2},\vec{r}} \\
|
||||
\tilde{\nabla} \cdot \hat{B}_{l-\frac{1}{2}, \vec{r} + \frac{1}{2}} &= 0 \\
|
||||
\hat{\nabla} \cdot \tilde{D}_{l,\vec{r}} &= \rho_{l,\vec{r}}
|
||||
\end{aligned}
|
||||
\]</div>
|
||||
|
||||
<p>with</p>
|
||||
<p>$$ \begin{aligned}
|
||||
\hat{B}<em _vec_r="\vec{r">{\vec{r}} &= \mu</em>} + \frac{1}{2}} \cdot \hat{H<em _vec_r="\vec{r">{\vec{r} + \frac{1}{2}} \
|
||||
\tilde{D}</em>
|
||||
\end{aligned} $$}} &= \epsilon_{\vec{r}} \cdot \tilde{E}_{\vec{r}</p>
|
||||
<div class="arithmatex">\[
|
||||
\begin{aligned}
|
||||
\hat{B}_{\vec{r}} &= \mu_{\vec{r} + \frac{1}{2}} \cdot \hat{H}_{\vec{r} + \frac{1}{2}} \\
|
||||
\tilde{D}_{\vec{r}} &= \epsilon_{\vec{r}} \cdot \tilde{E}_{\vec{r}}
|
||||
\end{aligned}
|
||||
\]</div>
|
||||
|
||||
<p>where the spatial subscripts are abbreviated as <span class="arithmatex">\(\vec{r} = (m, n, p)\)</span> and
|
||||
<span class="arithmatex">\(\vec{r} + \frac{1}{2} = (m + \frac{1}{2}, n + \frac{1}{2}, p + \frac{1}{2})\)</span>,
|
||||
<span class="arithmatex">\(\tilde{E}\)</span> and <span class="arithmatex">\(\hat{H}\)</span> are the electric and magnetic fields,
|
||||
|
|
@ -2177,94 +2211,108 @@ r - 1/2 = | / | /
|
|||
</code></pre></div>
|
||||
<p>The divergence equations can be derived by taking the divergence of the curl equations
|
||||
and combining them with charge continuity,
|
||||
$$ \hat{\nabla} \cdot \tilde{J} + \hat{\partial}_t \rho = 0 $$
|
||||
implying that the discrete Maxwell's equations do not produce spurious charges.</p>
|
||||
|
||||
<div class="arithmatex">\[ \hat{\nabla} \cdot \tilde{J} + \hat{\partial}_t \rho = 0 \]</div></p>
|
||||
<p>implying that the discrete Maxwell's equations do not produce spurious charges.</p>
|
||||
<h4 id="meanas.fdmath--wave-equation">Wave equation<a class="headerlink" href="#meanas.fdmath--wave-equation" title="Permanent link">¶</a></h4>
|
||||
<p>Taking the backward curl of the <span class="arithmatex">\(\tilde{\nabla} \times \tilde{E}\)</span> equation and
|
||||
replacing the resulting <span class="arithmatex">\(\hat{\nabla} \times \hat{H}\)</span> term using its respective equation,
|
||||
and setting <span class="arithmatex">\(\hat{M}\)</span> to zero, we can form the discrete wave equation:</p>
|
||||
<div class="arithmatex">\[
|
||||
\begin{aligned}
|
||||
\tilde{\nabla} \times \tilde{E}_{l,\vec{r}} &=
|
||||
\tilde{\nabla} \times \tilde{E}_{l,\vec{r}} &=
|
||||
-\tilde{\partial}_t \hat{B}_{l-\frac{1}{2}, \vec{r} + \frac{1}{2}}
|
||||
- \hat{M}_{l-1, \vec{r} + \frac{1}{2}} \\
|
||||
\mu^{-1}_{\vec{r} + \frac{1}{2}} \cdot \tilde{\nabla} \times \tilde{E}_{l,\vec{r}} &=
|
||||
\mu^{-1}_{\vec{r} + \frac{1}{2}} \cdot \tilde{\nabla} \times \tilde{E}_{l,\vec{r}} &=
|
||||
-\tilde{\partial}_t \hat{H}_{l-\frac{1}{2}, \vec{r} + \frac{1}{2}} \\
|
||||
\hat{\nabla} \times (\mu^{-1}_{\vec{r} + \frac{1}{2}} \cdot \tilde{\nabla} \times \tilde{E}_{l,\vec{r}}) &=
|
||||
\hat{\nabla} \times (\mu^{-1}_{\vec{r} + \frac{1}{2}} \cdot \tilde{\nabla} \times \tilde{E}_{l,\vec{r}}) &=
|
||||
\hat{\nabla} \times (-\tilde{\partial}_t \hat{H}_{l-\frac{1}{2}, \vec{r} + \frac{1}{2}}) \\
|
||||
\hat{\nabla} \times (\mu^{-1}_{\vec{r} + \frac{1}{2}} \cdot \tilde{\nabla} \times \tilde{E}_{l,\vec{r}}) &=
|
||||
\hat{\nabla} \times (\mu^{-1}_{\vec{r} + \frac{1}{2}} \cdot \tilde{\nabla} \times \tilde{E}_{l,\vec{r}}) &=
|
||||
-\tilde{\partial}_t \hat{\nabla} \times \hat{H}_{l-\frac{1}{2}, \vec{r} + \frac{1}{2}} \\
|
||||
\hat{\nabla} \times (\mu^{-1}_{\vec{r} + \frac{1}{2}} \cdot \tilde{\nabla} \times \tilde{E}_{l,\vec{r}}) &=
|
||||
\hat{\nabla} \times (\mu^{-1}_{\vec{r} + \frac{1}{2}} \cdot \tilde{\nabla} \times \tilde{E}_{l,\vec{r}}) &=
|
||||
-\tilde{\partial}_t \hat{\partial}_t \epsilon_{\vec{r}} \tilde{E}_{l, \vec{r}} + \hat{\partial}_t \tilde{J}_{l-\frac{1}{2},\vec{r}} \\
|
||||
\hat{\nabla} \times (\mu^{-1}_{\vec{r} + \frac{1}{2}} \cdot \tilde{\nabla} \times \tilde{E}_{l,\vec{r}})
|
||||
+ \tilde{\partial}_t \hat{\partial}_t \epsilon_{\vec{r}} \cdot \tilde{E}_{l, \vec{r}}
|
||||
&= \tilde{\partial}_t \tilde{J}_{l - \frac{1}{2}, \vec{r}}
|
||||
&= \tilde{\partial}_t \tilde{J}_{l - \frac{1}{2}, \vec{r}}
|
||||
\end{aligned}
|
||||
\]</div>
|
||||
|
||||
<h4 id="meanas.fdmath--frequency-domain">Frequency domain<a class="headerlink" href="#meanas.fdmath--frequency-domain" title="Permanent link">¶</a></h4>
|
||||
<p>We can substitute in a time-harmonic fields</p>
|
||||
<div class="arithmatex">\[
|
||||
\begin{aligned}
|
||||
\tilde{E}_{l, \vec{r}} &= \tilde{E}_{\vec{r}} e^{-\imath \omega l \Delta_t} \\
|
||||
\tilde{J}_{l, \vec{r}} &= \tilde{J}_{\vec{r}} e^{-\imath \omega (l - \frac{1}{2}) \Delta_t}
|
||||
\tilde{E}_{l, \vec{r}} &= \tilde{E}_{\vec{r}} e^{-\imath \omega l \Delta_t} \\
|
||||
\tilde{J}_{l, \vec{r}} &= \tilde{J}_{\vec{r}} e^{-\imath \omega (l - \frac{1}{2}) \Delta_t}
|
||||
\end{aligned}
|
||||
\]</div>
|
||||
|
||||
<p>resulting in</p>
|
||||
<div class="arithmatex">\[
|
||||
\begin{aligned}
|
||||
\tilde{\partial}_t &\Rightarrow (e^{ \imath \omega \Delta_t} - 1) / \Delta_t = \frac{-2 \imath}{\Delta_t} \sin(\omega \Delta_t / 2) e^{-\imath \omega \Delta_t / 2} = -\imath \Omega e^{-\imath \omega \Delta_t / 2}\\
|
||||
\hat{\partial}_t &\Rightarrow (1 - e^{-\imath \omega \Delta_t}) / \Delta_t = \frac{-2 \imath}{\Delta_t} \sin(\omega \Delta_t / 2) e^{ \imath \omega \Delta_t / 2} = -\imath \Omega e^{ \imath \omega \Delta_t / 2}\\
|
||||
\Omega &= 2 \sin(\omega \Delta_t / 2) / \Delta_t
|
||||
\tilde{\partial}_t &\Rightarrow (e^{ \imath \omega \Delta_t} - 1) / \Delta_t = \frac{-2 \imath}{\Delta_t} \sin(\omega \Delta_t / 2) e^{-\imath \omega \Delta_t / 2} = -\imath \Omega e^{-\imath \omega \Delta_t / 2}\\
|
||||
\hat{\partial}_t &\Rightarrow (1 - e^{-\imath \omega \Delta_t}) / \Delta_t = \frac{-2 \imath}{\Delta_t} \sin(\omega \Delta_t / 2) e^{ \imath \omega \Delta_t / 2} = -\imath \Omega e^{ \imath \omega \Delta_t / 2}\\
|
||||
\Omega &= 2 \sin(\omega \Delta_t / 2) / \Delta_t
|
||||
\end{aligned}
|
||||
\]</div>
|
||||
|
||||
<p>This gives the frequency-domain wave equation,</p>
|
||||
<div class="arithmatex">\[
|
||||
\hat{\nabla} \times (\mu^{-1}_{\vec{r} + \frac{1}{2}} \cdot \tilde{\nabla} \times \tilde{E}_{\vec{r}})
|
||||
-\Omega^2 \epsilon_{\vec{r}} \cdot \tilde{E}_{\vec{r}} = -\imath \Omega \tilde{J}_{\vec{r}} e^{\imath \omega \Delta_t / 2} \\
|
||||
\]</div>
|
||||
|
||||
<h4 id="meanas.fdmath--plane-waves-and-dispersion-relation">Plane waves and Dispersion relation<a class="headerlink" href="#meanas.fdmath--plane-waves-and-dispersion-relation" title="Permanent link">¶</a></h4>
|
||||
<p>With uniform material distribution and no sources</p>
|
||||
<div class="arithmatex">\[
|
||||
\begin{aligned}
|
||||
\mu_{\vec{r} + \frac{1}{2}} &= \mu \\
|
||||
\epsilon_{\vec{r}} &= \epsilon \\
|
||||
\tilde{J}_{\vec{r}} &= 0 \\
|
||||
\mu_{\vec{r} + \frac{1}{2}} &= \mu \\
|
||||
\epsilon_{\vec{r}} &= \epsilon \\
|
||||
\tilde{J}_{\vec{r}} &= 0 \\
|
||||
\end{aligned}
|
||||
\]</div>
|
||||
|
||||
<p>the frequency domain wave equation simplifies to</p>
|
||||
<div class="arithmatex">\[ \hat{\nabla} \times \tilde{\nabla} \times \tilde{E}_{\vec{r}} - \Omega^2 \epsilon \mu \tilde{E}_{\vec{r}} = 0 \]</div>
|
||||
|
||||
<p>Since <span class="arithmatex">\(\hat{\nabla} \cdot \tilde{E}_{\vec{r}} = 0\)</span>, we can simplify</p>
|
||||
<div class="arithmatex">\[
|
||||
\begin{aligned}
|
||||
\hat{\nabla} \times \tilde{\nabla} \times \tilde{E}_{\vec{r}}
|
||||
&= \tilde{\nabla}(\hat{\nabla} \cdot \tilde{E}_{\vec{r}}) - \hat{\nabla} \cdot \tilde{\nabla} \tilde{E}_{\vec{r}} \\
|
||||
&= - \hat{\nabla} \cdot \tilde{\nabla} \tilde{E}_{\vec{r}} \\
|
||||
&= - \tilde{\nabla}^2 \tilde{E}_{\vec{r}}
|
||||
&= \tilde{\nabla}(\hat{\nabla} \cdot \tilde{E}_{\vec{r}}) - \hat{\nabla} \cdot \tilde{\nabla} \tilde{E}_{\vec{r}} \\
|
||||
&= - \hat{\nabla} \cdot \tilde{\nabla} \tilde{E}_{\vec{r}} \\
|
||||
&= - \tilde{\nabla}^2 \tilde{E}_{\vec{r}}
|
||||
\end{aligned}
|
||||
\]</div>
|
||||
|
||||
<p>and we get</p>
|
||||
<div class="arithmatex">\[ \tilde{\nabla}^2 \tilde{E}_{\vec{r}} + \Omega^2 \epsilon \mu \tilde{E}_{\vec{r}} = 0 \]</div>
|
||||
|
||||
<p>We can convert this to three scalar-wave equations of the form</p>
|
||||
<div class="arithmatex">\[ (\tilde{\nabla}^2 + K^2) \phi_{\vec{r}} = 0 \]</div>
|
||||
|
||||
<p>with <span class="arithmatex">\(K^2 = \Omega^2 \mu \epsilon\)</span>. Now we let</p>
|
||||
<div class="arithmatex">\[ \phi_{\vec{r}} = A e^{\imath (k_x m \Delta_x + k_y n \Delta_y + k_z p \Delta_z)} \]</div>
|
||||
|
||||
<p>resulting in</p>
|
||||
<div class="arithmatex">\[
|
||||
\begin{aligned}
|
||||
\tilde{\partial}_x &\Rightarrow (e^{ \imath k_x \Delta_x} - 1) / \Delta_t = \frac{-2 \imath}{\Delta_x} \sin(k_x \Delta_x / 2) e^{ \imath k_x \Delta_x / 2} = \imath K_x e^{ \imath k_x \Delta_x / 2}\\
|
||||
\hat{\partial}_x &\Rightarrow (1 - e^{-\imath k_x \Delta_x}) / \Delta_t = \frac{-2 \imath}{\Delta_x} \sin(k_x \Delta_x / 2) e^{-\imath k_x \Delta_x / 2} = \imath K_x e^{-\imath k_x \Delta_x / 2}\\
|
||||
K_x &= 2 \sin(k_x \Delta_x / 2) / \Delta_x \\
|
||||
\tilde{\partial}_x &\Rightarrow (e^{ \imath k_x \Delta_x} - 1) / \Delta_t = \frac{-2 \imath}{\Delta_x} \sin(k_x \Delta_x / 2) e^{ \imath k_x \Delta_x / 2} = \imath K_x e^{ \imath k_x \Delta_x / 2}\\
|
||||
\hat{\partial}_x &\Rightarrow (1 - e^{-\imath k_x \Delta_x}) / \Delta_t = \frac{-2 \imath}{\Delta_x} \sin(k_x \Delta_x / 2) e^{-\imath k_x \Delta_x / 2} = \imath K_x e^{-\imath k_x \Delta_x / 2}\\
|
||||
K_x &= 2 \sin(k_x \Delta_x / 2) / \Delta_x \\
|
||||
\end{aligned}
|
||||
\]</div>
|
||||
|
||||
<p>with similar expressions for the y and z dimnsions (and <span class="arithmatex">\(K_y, K_z\)</span>).</p>
|
||||
<p>This implies</p>
|
||||
<div class="arithmatex">\[
|
||||
\tilde{\nabla}^2 = -(K_x^2 + K_y^2 + K_z^2) \phi_{\vec{r}} \\
|
||||
K_x^2 + K_y^2 + K_z^2 = \Omega^2 \mu \epsilon = \Omega^2 / c^2
|
||||
\]</div>
|
||||
|
||||
<p>where <span class="arithmatex">\(c = \sqrt{\mu \epsilon}\)</span>.</p>
|
||||
<p>Assuming real <span class="arithmatex">\((k_x, k_y, k_z), \omega\)</span> will be real only if</p>
|
||||
<div class="arithmatex">\[ c^2 \Delta_t^2 = \frac{\Delta_t^2}{\mu \epsilon} < 1/(\frac{1}{\Delta_x^2} + \frac{1}{\Delta_y^2} + \frac{1}{\Delta_z^2}) \]</div>
|
||||
<div class="arithmatex">\[ c^2 \Delta_t^2 = \frac{\Delta_t^2}{\mu \epsilon} < 1/(\frac{1}{\Delta_x^2} + \frac{1}{\Delta_y^2} + \frac{1}{\Delta_z^2}) \]</div>
|
||||
|
||||
<p>If <span class="arithmatex">\(\Delta_x = \Delta_y = \Delta_z\)</span>, this simplifies to <span class="arithmatex">\(c \Delta_t < \Delta_x / \sqrt{3}\)</span>.
|
||||
This last form can be interpreted as enforcing causality; the distance that light
|
||||
travels in one timestep (i.e., <span class="arithmatex">\(c \Delta_t\)</span>) must be less than the diagonal
|
||||
|
|
@ -2461,15 +2509,16 @@ mu = [mu_xx, mu_yy, mu_zz]
|
|||
</code></pre></div>
|
||||
<p>or</p>
|
||||
<div class="arithmatex">\[
|
||||
\epsilon = \begin{bmatrix} \epsilon_{xx} & 0 & 0 \\
|
||||
0 & \epsilon_{yy} & 0 \\
|
||||
0 & 0 & \epsilon_{zz} \end{bmatrix}
|
||||
$$
|
||||
$$
|
||||
\mu = \begin{bmatrix} \mu_{xx} & 0 & 0 \\
|
||||
0 & \mu_{yy} & 0 \\
|
||||
0 & 0 & \mu_{zz} \end{bmatrix}
|
||||
\epsilon = \begin{bmatrix} \epsilon_{xx} & 0 & 0 \\
|
||||
0 & \epsilon_{yy} & 0 \\
|
||||
0 & 0 & \epsilon_{zz} \end{bmatrix}
|
||||
\]</div>
|
||||
<div class="arithmatex">\[
|
||||
\mu = \begin{bmatrix} \mu_{xx} & 0 & 0 \\
|
||||
0 & \mu_{yy} & 0 \\
|
||||
0 & 0 & \mu_{zz} \end{bmatrix}
|
||||
\]</div>
|
||||
|
||||
<p>where the off-diagonal terms (e.g. <code>epsilon_xy</code>) are assumed to be zero.</p>
|
||||
<p>High-accuracy volumetric integration of shapes on multiple grids can be performed
|
||||
by the <a href="https://mpxd.net/code/jan/gridlock">gridlock</a> module.</p>
|
||||
|
|
|
|||
|
|
@ -809,6 +809,50 @@
|
|||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#meanas.fdtd.phasor.temporal_phasor" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
<code class="doc-symbol doc-symbol-toc doc-symbol-function"></code> temporal_phasor
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#meanas.fdtd.phasor.temporal_phasor_scale" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
<code class="doc-symbol doc-symbol-toc doc-symbol-function"></code> temporal_phasor_scale
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#meanas.fdtd.phasor.real_injection_scale" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
<code class="doc-symbol doc-symbol-toc doc-symbol-function"></code> real_injection_scale
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#meanas.fdtd.phasor.reconstruct_real" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
<code class="doc-symbol doc-symbol-toc doc-symbol-function"></code> reconstruct_real
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
|
|
@ -842,6 +886,39 @@
|
|||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#meanas.fdtd.phasor.reconstruct_real_e" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
<code class="doc-symbol doc-symbol-toc doc-symbol-function"></code> reconstruct_real_e
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#meanas.fdtd.phasor.reconstruct_real_h" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
<code class="doc-symbol doc-symbol-toc doc-symbol-function"></code> reconstruct_real_h
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#meanas.fdtd.phasor.reconstruct_real_j" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
<code class="doc-symbol doc-symbol-toc doc-symbol-function"></code> reconstruct_real_j
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
|
@ -1223,6 +1300,50 @@
|
|||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#meanas.fdtd.phasor.temporal_phasor" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
<code class="doc-symbol doc-symbol-toc doc-symbol-function"></code> temporal_phasor
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#meanas.fdtd.phasor.temporal_phasor_scale" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
<code class="doc-symbol doc-symbol-toc doc-symbol-function"></code> temporal_phasor_scale
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#meanas.fdtd.phasor.real_injection_scale" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
<code class="doc-symbol doc-symbol-toc doc-symbol-function"></code> real_injection_scale
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#meanas.fdtd.phasor.reconstruct_real" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
<code class="doc-symbol doc-symbol-toc doc-symbol-function"></code> reconstruct_real
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
|
|
@ -1256,6 +1377,39 @@
|
|||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#meanas.fdtd.phasor.reconstruct_real_e" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
<code class="doc-symbol doc-symbol-toc doc-symbol-function"></code> reconstruct_real_e
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#meanas.fdtd.phasor.reconstruct_real_h" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
<code class="doc-symbol doc-symbol-toc doc-symbol-function"></code> reconstruct_real_h
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#meanas.fdtd.phasor.reconstruct_real_j" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
<code class="doc-symbol doc-symbol-toc doc-symbol-function"></code> reconstruct_real_j
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
|
@ -1301,7 +1455,8 @@ mathematical background.</p>
|
|||
<h3 id="meanas.fdtd--timestep">Timestep<a class="headerlink" href="#meanas.fdtd--timestep" title="Permanent link">¶</a></h3>
|
||||
<p>From the discussion of "Plane waves and the Dispersion relation" in <code>meanas.fdmath</code>,
|
||||
we have</p>
|
||||
<div class="arithmatex">\[ c^2 \Delta_t^2 = \frac{\Delta_t^2}{\mu \epsilon} < 1/(\frac{1}{\Delta_x^2} + \frac{1}{\Delta_y^2} + \frac{1}{\Delta_z^2}) \]</div>
|
||||
<div class="arithmatex">\[ c^2 \Delta_t^2 = \frac{\Delta_t^2}{\mu \epsilon} < 1/(\frac{1}{\Delta_x^2} + \frac{1}{\Delta_y^2} + \frac{1}{\Delta_z^2}) \]</div>
|
||||
|
||||
<p>or, if <span class="arithmatex">\(\Delta_x = \Delta_y = \Delta_z\)</span>, then <span class="arithmatex">\(c \Delta_t < \frac{\Delta_x}{\sqrt{3}}\)</span>.</p>
|
||||
<p>Based on this, we can set</p>
|
||||
<div class="highlight"><pre><span></span><code>dt = sqrt(mu.min() * epsilon.min()) / sqrt(1/dx_min**2 + 1/dy_min**2 + 1/dz_min**2)
|
||||
|
|
@ -1309,54 +1464,58 @@ we have</p>
|
|||
<p>The <code>dx_min</code>, <code>dy_min</code>, <code>dz_min</code> should be the minimum value across both the base and derived grids.</p>
|
||||
<h3 id="meanas.fdtd--poynting-vector-and-energy-conservation">Poynting Vector and Energy Conservation<a class="headerlink" href="#meanas.fdtd--poynting-vector-and-energy-conservation" title="Permanent link">¶</a></h3>
|
||||
<p>Let</p>
|
||||
<div class="arithmatex">\[ \begin{aligned}
|
||||
\tilde{S}_{l, l', \vec{r}} &=& &\tilde{E}_{l, \vec{r}} \otimes \hat{H}_{l', \vec{r} + \frac{1}{2}} \\
|
||||
&=& &\vec{x} (\tilde{E}^y_{l,m+1,n,p} \hat{H}^z_{l',\vec{r} + \frac{1}{2}} - \tilde{E}^z_{l,m+1,n,p} \hat{H}^y_{l', \vec{r} + \frac{1}{2}}) \\
|
||||
& &+ &\vec{y} (\tilde{E}^z_{l,m,n+1,p} \hat{H}^x_{l',\vec{r} + \frac{1}{2}} - \tilde{E}^x_{l,m,n+1,p} \hat{H}^z_{l', \vec{r} + \frac{1}{2}}) \\
|
||||
& &+ &\vec{z} (\tilde{E}^x_{l,m,n,p+1} \hat{H}^y_{l',\vec{r} + \frac{1}{2}} - \tilde{E}^y_{l,m,n,p+1} \hat{H}^z_{l', \vec{r} + \frac{1}{2}})
|
||||
<div class="arithmatex">\[
|
||||
\begin{aligned}
|
||||
\tilde{S}_{l, l', \vec{r}} &=& &\tilde{E}_{l, \vec{r}} \otimes \hat{H}_{l', \vec{r} + \frac{1}{2}} \\
|
||||
&=& &\vec{x} (\tilde{E}^y_{l,m+1,n,p} \hat{H}^z_{l',\vec{r} + \frac{1}{2}} - \tilde{E}^z_{l,m+1,n,p} \hat{H}^y_{l', \vec{r} + \frac{1}{2}}) \\
|
||||
& &+ &\vec{y} (\tilde{E}^z_{l,m,n+1,p} \hat{H}^x_{l',\vec{r} + \frac{1}{2}} - \tilde{E}^x_{l,m,n+1,p} \hat{H}^z_{l', \vec{r} + \frac{1}{2}}) \\
|
||||
& &+ &\vec{z} (\tilde{E}^x_{l,m,n,p+1} \hat{H}^y_{l',\vec{r} + \frac{1}{2}} - \tilde{E}^y_{l,m,n,p+1} \hat{H}^z_{l', \vec{r} + \frac{1}{2}})
|
||||
\end{aligned}
|
||||
\]</div>
|
||||
|
||||
<p>where <span class="arithmatex">\(\vec{r} = (m, n, p)\)</span> and <span class="arithmatex">\(\otimes\)</span> is a modified cross product
|
||||
in which the <span class="arithmatex">\(\tilde{E}\)</span> terms are shifted as indicated.</p>
|
||||
<p>By taking the divergence and rearranging terms, we can show that</p>
|
||||
<div class="arithmatex">\[
|
||||
\begin{aligned}
|
||||
\hat{\nabla} \cdot \tilde{S}_{l, l', \vec{r}}
|
||||
&= \hat{\nabla} \cdot (\tilde{E}_{l, \vec{r}} \otimes \hat{H}_{l', \vec{r} + \frac{1}{2}}) \\
|
||||
&= \hat{H}_{l', \vec{r} + \frac{1}{2}} \cdot \tilde{\nabla} \times \tilde{E}_{l, \vec{r}} -
|
||||
&= \hat{\nabla} \cdot (\tilde{E}_{l, \vec{r}} \otimes \hat{H}_{l', \vec{r} + \frac{1}{2}}) \\
|
||||
&= \hat{H}_{l', \vec{r} + \frac{1}{2}} \cdot \tilde{\nabla} \times \tilde{E}_{l, \vec{r}} -
|
||||
\tilde{E}_{l, \vec{r}} \cdot \hat{\nabla} \times \hat{H}_{l', \vec{r} + \frac{1}{2}} \\
|
||||
&= \hat{H}_{l', \vec{r} + \frac{1}{2}} \cdot
|
||||
&= \hat{H}_{l', \vec{r} + \frac{1}{2}} \cdot
|
||||
(-\tilde{\partial}_t \mu_{\vec{r} + \frac{1}{2}} \hat{H}_{l - \frac{1}{2}, \vec{r} + \frac{1}{2}} -
|
||||
\hat{M}_{l, \vec{r} + \frac{1}{2}}) -
|
||||
\tilde{E}_{l, \vec{r}} \cdot (\hat{\partial}_t \tilde{\epsilon}_{\vec{r}} \tilde{E}_{l'+\frac{1}{2}, \vec{r}} +
|
||||
\tilde{J}_{l', \vec{r}}) \\
|
||||
&= \hat{H}_{l'} \cdot (-\mu / \Delta_t)(\hat{H}_{l + \frac{1}{2}} - \hat{H}_{l - \frac{1}{2}}) -
|
||||
&= \hat{H}_{l'} \cdot (-\mu / \Delta_t)(\hat{H}_{l + \frac{1}{2}} - \hat{H}_{l - \frac{1}{2}}) -
|
||||
\tilde{E}_l \cdot (\epsilon / \Delta_t )(\tilde{E}_{l'+\frac{1}{2}} - \tilde{E}_{l'-\frac{1}{2}})
|
||||
- \hat{H}_{l'} \cdot \hat{M}_{l} - \tilde{E}_l \cdot \tilde{J}_{l'} \\
|
||||
\end{aligned}
|
||||
\]</div>
|
||||
|
||||
<p>where in the last line the spatial subscripts have been dropped to emphasize
|
||||
the time subscripts <span class="arithmatex">\(l, l'\)</span>, i.e.</p>
|
||||
<div class="arithmatex">\[
|
||||
\begin{aligned}
|
||||
\tilde{E}_l &= \tilde{E}_{l, \vec{r}} \\
|
||||
\hat{H}_l &= \tilde{H}_{l, \vec{r} + \frac{1}{2}} \\
|
||||
\tilde{\epsilon} &= \tilde{\epsilon}_{\vec{r}} \\
|
||||
\tilde{E}_l &= \tilde{E}_{l, \vec{r}} \\
|
||||
\hat{H}_l &= \tilde{H}_{l, \vec{r} + \frac{1}{2}} \\
|
||||
\tilde{\epsilon} &= \tilde{\epsilon}_{\vec{r}} \\
|
||||
\end{aligned}
|
||||
\]</div>
|
||||
|
||||
<p>etc.
|
||||
For <span class="arithmatex">\(l' = l + \frac{1}{2}\)</span> we get</p>
|
||||
<div class="arithmatex">\[
|
||||
\begin{aligned}
|
||||
\hat{\nabla} \cdot \tilde{S}_{l, l + \frac{1}{2}}
|
||||
&= \hat{H}_{l + \frac{1}{2}} \cdot
|
||||
&= \hat{H}_{l + \frac{1}{2}} \cdot
|
||||
(-\mu / \Delta_t)(\hat{H}_{l + \frac{1}{2}} - \hat{H}_{l - \frac{1}{2}}) -
|
||||
\tilde{E}_l \cdot (\epsilon / \Delta_t)(\tilde{E}_{l+1} - \tilde{E}_l)
|
||||
- \hat{H}_{l'} \cdot \hat{M}_l - \tilde{E}_l \cdot \tilde{J}_{l + \frac{1}{2}} \\
|
||||
&= (-\mu / \Delta_t)(\hat{H}^2_{l + \frac{1}{2}} - \hat{H}_{l + \frac{1}{2}} \cdot \hat{H}_{l - \frac{1}{2}}) -
|
||||
&= (-\mu / \Delta_t)(\hat{H}^2_{l + \frac{1}{2}} - \hat{H}_{l + \frac{1}{2}} \cdot \hat{H}_{l - \frac{1}{2}}) -
|
||||
(\epsilon / \Delta_t)(\tilde{E}_{l+1} \cdot \tilde{E}_l - \tilde{E}^2_l)
|
||||
- \hat{H}_{l'} \cdot \hat{M}_l - \tilde{E}_l \cdot \tilde{J}_{l + \frac{1}{2}} \\
|
||||
&= -(\mu \hat{H}^2_{l + \frac{1}{2}}
|
||||
&= -(\mu \hat{H}^2_{l + \frac{1}{2}}
|
||||
+\epsilon \tilde{E}_{l+1} \cdot \tilde{E}_l) / \Delta_t \\
|
||||
+(\mu \hat{H}_{l + \frac{1}{2}} \cdot \hat{H}_{l - \frac{1}{2}}
|
||||
+\epsilon \tilde{E}^2_l) / \Delta_t \\
|
||||
|
|
@ -1364,11 +1523,12 @@ For <span class="arithmatex">\(l' = l + \frac{1}{2}\)</span> we get</p>
|
|||
- \tilde{E}_l \cdot \tilde{J}_{l+\frac{1}{2}} \\
|
||||
\end{aligned}
|
||||
\]</div>
|
||||
|
||||
<p>and for <span class="arithmatex">\(l' = l - \frac{1}{2}\)</span>,</p>
|
||||
<div class="arithmatex">\[
|
||||
\begin{aligned}
|
||||
\hat{\nabla} \cdot \tilde{S}_{l, l - \frac{1}{2}}
|
||||
&= (\mu \hat{H}^2_{l - \frac{1}{2}}
|
||||
&= (\mu \hat{H}^2_{l - \frac{1}{2}}
|
||||
+\epsilon \tilde{E}_{l-1} \cdot \tilde{E}_l) / \Delta_t \\
|
||||
-(\mu \hat{H}_{l + \frac{1}{2}} \cdot \hat{H}_{l - \frac{1}{2}}
|
||||
+\epsilon \tilde{E}^2_l) / \Delta_t \\
|
||||
|
|
@ -1376,28 +1536,31 @@ For <span class="arithmatex">\(l' = l + \frac{1}{2}\)</span> we get</p>
|
|||
- \tilde{E}_l \cdot \tilde{J}_{l-\frac{1}{2}} \\
|
||||
\end{aligned}
|
||||
\]</div>
|
||||
|
||||
<p>These two results form the discrete time-domain analogue to Poynting's theorem.
|
||||
They hint at the expressions for the energy, which can be calculated at the same
|
||||
time-index as either the E or H field:</p>
|
||||
<div class="arithmatex">\[
|
||||
\begin{aligned}
|
||||
U_l &= \epsilon \tilde{E}^2_l + \mu \hat{H}_{l + \frac{1}{2}} \cdot \hat{H}_{l - \frac{1}{2}} \\
|
||||
U_{l + \frac{1}{2}} &= \epsilon \tilde{E}_l \cdot \tilde{E}_{l + 1} + \mu \hat{H}^2_{l + \frac{1}{2}} \\
|
||||
U_l &= \epsilon \tilde{E}^2_l + \mu \hat{H}_{l + \frac{1}{2}} \cdot \hat{H}_{l - \frac{1}{2}} \\
|
||||
U_{l + \frac{1}{2}} &= \epsilon \tilde{E}_l \cdot \tilde{E}_{l + 1} + \mu \hat{H}^2_{l + \frac{1}{2}} \\
|
||||
\end{aligned}
|
||||
\]</div>
|
||||
|
||||
<p>Rewriting the Poynting theorem in terms of the energy expressions,</p>
|
||||
<div class="arithmatex">\[
|
||||
\begin{aligned}
|
||||
(U_{l+\frac{1}{2}} - U_l) / \Delta_t
|
||||
&= -\hat{\nabla} \cdot \tilde{S}_{l, l + \frac{1}{2}} \\
|
||||
&= -\hat{\nabla} \cdot \tilde{S}_{l, l + \frac{1}{2}} \\
|
||||
- \hat{H}_{l+\frac{1}{2}} \cdot \hat{M}_l \\
|
||||
- \tilde{E}_l \cdot \tilde{J}_{l+\frac{1}{2}} \\
|
||||
(U_l - U_{l-\frac{1}{2}}) / \Delta_t
|
||||
&= -\hat{\nabla} \cdot \tilde{S}_{l, l - \frac{1}{2}} \\
|
||||
&= -\hat{\nabla} \cdot \tilde{S}_{l, l - \frac{1}{2}} \\
|
||||
- \hat{H}_{l-\frac{1}{2}} \cdot \hat{M}_l \\
|
||||
- \tilde{E}_l \cdot \tilde{J}_{l-\frac{1}{2}} \\
|
||||
\end{aligned}
|
||||
\]</div>
|
||||
|
||||
<p>This result is exact and should practically hold to within numerical precision. No time-
|
||||
or spatial-averaging is necessary.</p>
|
||||
<p>Note that each value of <span class="arithmatex">\(J\)</span> contributes to the energy twice (i.e. once per field update)
|
||||
|
|
@ -1408,16 +1571,46 @@ extract the frequency-domain response by performing an on-the-fly Fourier transf
|
|||
of the time-domain fields.</p>
|
||||
<p><code>accumulate_phasor</code> in <code>meanas.fdtd.phasor</code> performs the phase accumulation for one
|
||||
or more target frequencies, while leaving source normalization and simulation-loop
|
||||
policy to the caller. Convenience wrappers <code>accumulate_phasor_e</code>,
|
||||
<code>accumulate_phasor_h</code>, and <code>accumulate_phasor_j</code> apply the usual Yee time offsets.
|
||||
policy to the caller. <code>temporal_phasor(...)</code> and <code>temporal_phasor_scale(...)</code>
|
||||
apply the same Fourier sum to a scalar waveform, which is useful when a pulsed
|
||||
source envelope must be normalized before being applied to a point source or
|
||||
mode source. <code>real_injection_scale(...)</code> is the corresponding helper for the
|
||||
common real-valued injection pattern <code>numpy.real(scale * waveform)</code>. Convenience
|
||||
wrappers <code>accumulate_phasor_e</code>, <code>accumulate_phasor_h</code>, and <code>accumulate_phasor_j</code>
|
||||
apply the usual Yee time offsets. <code>reconstruct_real(...)</code> and the corresponding
|
||||
<code>reconstruct_real_e/h/j(...)</code> wrappers perform the inverse operation, converting
|
||||
phasors back into real-valued field snapshots at explicit Yee-aligned times.
|
||||
For scalar <code>omega</code>, the reconstruction helpers accept either a plain field
|
||||
phasor or the batched <code>(1, *sample_shape)</code> form used by the accumulator helpers.
|
||||
The helpers accumulate</p>
|
||||
<div class="arithmatex">\[ \Delta_t \sum_l w_l e^{-i \omega t_l} f_l \]</div>
|
||||
|
||||
<p>with caller-provided sample times and weights. In this codebase the matching
|
||||
electric-current convention is typically <code>E -= dt * J / epsilon</code> in FDTD and
|
||||
<code>-i \omega J</code> on the right-hand side of the FDFD wave equation.</p>
|
||||
<p>For FDTD/FDFD equivalence, this phasor path is the primary comparison workflow.
|
||||
It isolates the guided <code>+\omega</code> response that the frequency-domain solver
|
||||
targets directly, regardless of whether the underlying FDTD run used real- or
|
||||
complex-valued fields.</p>
|
||||
<p>For exact pulsed FDTD/FDFD equivalence it is often simplest to keep the
|
||||
injected source, fields, and CPML auxiliary state complex-valued. The
|
||||
<code>real_injection_scale(...)</code> helper is instead for the more ordinary one-run
|
||||
real-valued source path, where the intended positive-frequency waveform is
|
||||
injected through <code>numpy.real(scale * waveform)</code> and any remaining negative-
|
||||
frequency leakage is controlled by the pulse bandwidth and run length.</p>
|
||||
<p><code>reconstruct_real(...)</code> is for a different question: given a phasor, what late
|
||||
real-valued field snapshot should it produce? That raw-snapshot comparison is
|
||||
stricter and noisier because a monitor plane generally contains both the guided
|
||||
field and the remaining orthogonal content,</p>
|
||||
<div class="arithmatex">\[ E_{\text{monitor}} = E_{\text{guided}} + E_{\text{residual}} . \]</div>
|
||||
|
||||
<p>Phasor/modal comparisons mostly validate the guided <code>+\omega</code> term. Raw
|
||||
real-field comparisons expose both terms at once, so they should be treated as
|
||||
secondary diagnostics rather than the main solver-equivalence benchmark.</p>
|
||||
<p>The Ricker wavelet (normalized second derivative of a Gaussian) is commonly used for the pulse
|
||||
shape. It can be written</p>
|
||||
<div class="arithmatex">\[ f_r(t) = (1 - \frac{1}{2} (\omega (t - \tau))^2) e^{-(\frac{\omega (t - \tau)}{2})^2} \]</div>
|
||||
|
||||
<p>with <span class="arithmatex">\(\tau > \frac{2 * \pi}{\omega}\)</span> as a minimum delay to avoid a discontinuity at
|
||||
t=0 (assuming the source is off for t<0 this gives <span class="arithmatex">\(\sim 10^{-3}\)</span> error at t=0).</p>
|
||||
<h3 id="meanas.fdtd--boundary-conditions">Boundary conditions<a class="headerlink" href="#meanas.fdtd--boundary-conditions" title="Permanent link">¶</a></h3>
|
||||
|
|
@ -1447,6 +1640,7 @@ coordinate system in both places:</p>
|
|||
<div class="arithmatex">\[
|
||||
E \leftarrow E - \Delta_t J / \epsilon
|
||||
\]</div>
|
||||
|
||||
<p>which matches the FDFD right-hand side</p>
|
||||
<div class="arithmatex">\[
|
||||
-i \omega J.
|
||||
|
|
@ -2390,19 +2584,20 @@ boundaries of the corresponding <code>U</code> cell. For example,</p>
|
|||
<a id="__codelineno-0-15" name="__codelineno-0-15" href="#__codelineno-0-15"></a> assert_close(sum(planes), du_half_h2e[mask])
|
||||
</code></pre></div>
|
||||
<p>(see <code>meanas.tests.test_fdtd.test_poynting_planes</code>)</p>
|
||||
<p>The full relationship is
|
||||
$$
|
||||
<p>The full relationship is</p>
|
||||
<div class="arithmatex">\[
|
||||
\begin{aligned}
|
||||
(U_{l+\frac{1}{2}} - U_l) / \Delta_t
|
||||
&= -\hat{\nabla} \cdot \tilde{S}<em l_frac_1="l+\frac{1">{l, l + \frac{1}{2}} \
|
||||
- \hat{H}</em>}{2}} \cdot \hat{M<em l_frac_1="l+\frac{1">l \
|
||||
- \tilde{E}_l \cdot \tilde{J}</em> \
|
||||
&= -\hat{\nabla} \cdot \tilde{S}_{l, l + \frac{1}{2}} \\
|
||||
- \hat{H}_{l+\frac{1}{2}} \cdot \hat{M}_l \\
|
||||
- \tilde{E}_l \cdot \tilde{J}_{l+\frac{1}{2}} \\
|
||||
(U_l - U_{l-\frac{1}{2}}) / \Delta_t
|
||||
&= -\hat{\nabla} \cdot \tilde{S}}{2}<em l-_frac_1="l-\frac{1">{l, l - \frac{1}{2}} \
|
||||
- \hat{H}</em>}{2}} \cdot \hat{M<em l-_frac_1="l-\frac{1">l \
|
||||
- \tilde{E}_l \cdot \tilde{J}</em> \
|
||||
&= -\hat{\nabla} \cdot \tilde{S}_{l, l - \frac{1}{2}} \\
|
||||
- \hat{H}_{l-\frac{1}{2}} \cdot \hat{M}_l \\
|
||||
- \tilde{E}_l \cdot \tilde{J}_{l-\frac{1}{2}} \\
|
||||
\end{aligned}
|
||||
$$}{2}</p>
|
||||
\]</div>
|
||||
|
||||
<p>These equalities are exact and should practically hold to within numerical precision.
|
||||
No time- or spatial-averaging is necessary. (See <code>meanas.fdtd</code> docs for derivation.)</p>
|
||||
|
||||
|
|
@ -3579,6 +3774,18 @@ the sampling policy. The accumulated quantity is</p>
|
|||
<li><code>accumulate_phasor_h(..., step=l)</code> for <code>H_{l + 1/2}</code></li>
|
||||
<li><code>accumulate_phasor_j(..., step=l)</code> for <code>J_{l + 1/2}</code></li>
|
||||
</ul>
|
||||
<p><code>temporal_phasor(...)</code> and <code>temporal_phasor_scale(...)</code> apply the same Fourier
|
||||
sum to a 1D scalar waveform. They are useful for normalizing a pulsed source
|
||||
before that scalar waveform is applied to a point source or spatial mode source.
|
||||
<code>real_injection_scale(...)</code> is a companion helper for the common real-valued
|
||||
injection pattern <code>numpy.real(scale * waveform)</code>, where <code>waveform</code> is the
|
||||
analytic positive-frequency signal and the injected real current should still
|
||||
produce a desired phasor response.
|
||||
<code>reconstruct_real(...)</code> and its <code>E/H/J</code> wrappers perform the inverse operation:
|
||||
they turn one or more phasors back into real-valued field snapshots at explicit
|
||||
Yee-aligned sample times. For a scalar target frequency they accept either a
|
||||
plain field phasor or the batched <code>(1, *sample_shape)</code> form used elsewhere in
|
||||
this module.</p>
|
||||
<p>These helpers do not choose warmup/accumulation windows or pulse-envelope
|
||||
normalization. They also do not impose a current sign convention. In this
|
||||
codebase, electric-current injection normally appears as <code>E -= dt * J / epsilon</code>,
|
||||
|
|
@ -3650,6 +3857,154 @@ factor was derived from a discrete sum that already includes <code>dt</code>, pa
|
|||
<div class="doc doc-object doc-function">
|
||||
|
||||
|
||||
<h3 id="meanas.fdtd.phasor.temporal_phasor" class="doc doc-heading">
|
||||
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">temporal_phasor</span>
|
||||
|
||||
|
||||
<a href="#meanas.fdtd.phasor.temporal_phasor" class="headerlink" title="Permanent link">¶</a></h3>
|
||||
<div class="doc-signature highlight"><pre><span></span><code><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a><span class="nf">temporal_phasor</span><span class="p">(</span>
|
||||
<a id="__codelineno-0-2" name="__codelineno-0-2" href="#__codelineno-0-2"></a> <span class="n">samples</span><span class="p">:</span> <span class="n">ArrayLike</span><span class="p">,</span>
|
||||
<a id="__codelineno-0-3" name="__codelineno-0-3" href="#__codelineno-0-3"></a> <span class="n">omegas</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<a id="__codelineno-0-4" name="__codelineno-0-4" href="#__codelineno-0-4"></a> <span class="o">|</span> <span class="nb">complex</span>
|
||||
<a id="__codelineno-0-5" name="__codelineno-0-5" href="#__codelineno-0-5"></a> <span class="o">|</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">float</span> <span class="o">|</span> <span class="nb">complex</span><span class="p">]</span>
|
||||
<a id="__codelineno-0-6" name="__codelineno-0-6" href="#__codelineno-0-6"></a> <span class="o">|</span> <span class="n">NDArray</span><span class="p">,</span>
|
||||
<a id="__codelineno-0-7" name="__codelineno-0-7" href="#__codelineno-0-7"></a> <span class="n">dt</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
|
||||
<a id="__codelineno-0-8" name="__codelineno-0-8" href="#__codelineno-0-8"></a> <span class="o">*</span><span class="p">,</span>
|
||||
<a id="__codelineno-0-9" name="__codelineno-0-9" href="#__codelineno-0-9"></a> <span class="n">start_step</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
|
||||
<a id="__codelineno-0-10" name="__codelineno-0-10" href="#__codelineno-0-10"></a> <span class="n">offset_steps</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mf">0.0</span><span class="p">,</span>
|
||||
<a id="__codelineno-0-11" name="__codelineno-0-11" href="#__codelineno-0-11"></a><span class="p">)</span> <span class="o">-></span> <span class="n">NDArray</span><span class="p">[</span><span class="n">numpy</span><span class="o">.</span><span class="n">complexfloating</span><span class="p">]</span>
|
||||
</code></pre></div>
|
||||
|
||||
<div class="doc doc-contents ">
|
||||
|
||||
<p>Fourier-project a 1D temporal waveform onto one or more angular frequencies.</p>
|
||||
<p>The returned quantity is</p>
|
||||
<div class="highlight"><pre><span></span><code>dt * sum(exp(-1j * omega * t_step) * samples[step_index])
|
||||
</code></pre></div>
|
||||
<p>where <code>t_step = (start_step + step_index + offset_steps) * dt</code>.</p>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="doc doc-object doc-function">
|
||||
|
||||
|
||||
<h3 id="meanas.fdtd.phasor.temporal_phasor_scale" class="doc doc-heading">
|
||||
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">temporal_phasor_scale</span>
|
||||
|
||||
|
||||
<a href="#meanas.fdtd.phasor.temporal_phasor_scale" class="headerlink" title="Permanent link">¶</a></h3>
|
||||
<div class="doc-signature highlight"><pre><span></span><code><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a><span class="nf">temporal_phasor_scale</span><span class="p">(</span>
|
||||
<a id="__codelineno-0-2" name="__codelineno-0-2" href="#__codelineno-0-2"></a> <span class="n">samples</span><span class="p">:</span> <span class="n">ArrayLike</span><span class="p">,</span>
|
||||
<a id="__codelineno-0-3" name="__codelineno-0-3" href="#__codelineno-0-3"></a> <span class="n">omegas</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<a id="__codelineno-0-4" name="__codelineno-0-4" href="#__codelineno-0-4"></a> <span class="o">|</span> <span class="nb">complex</span>
|
||||
<a id="__codelineno-0-5" name="__codelineno-0-5" href="#__codelineno-0-5"></a> <span class="o">|</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">float</span> <span class="o">|</span> <span class="nb">complex</span><span class="p">]</span>
|
||||
<a id="__codelineno-0-6" name="__codelineno-0-6" href="#__codelineno-0-6"></a> <span class="o">|</span> <span class="n">NDArray</span><span class="p">,</span>
|
||||
<a id="__codelineno-0-7" name="__codelineno-0-7" href="#__codelineno-0-7"></a> <span class="n">dt</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
|
||||
<a id="__codelineno-0-8" name="__codelineno-0-8" href="#__codelineno-0-8"></a> <span class="o">*</span><span class="p">,</span>
|
||||
<a id="__codelineno-0-9" name="__codelineno-0-9" href="#__codelineno-0-9"></a> <span class="n">start_step</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
|
||||
<a id="__codelineno-0-10" name="__codelineno-0-10" href="#__codelineno-0-10"></a> <span class="n">offset_steps</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mf">0.0</span><span class="p">,</span>
|
||||
<a id="__codelineno-0-11" name="__codelineno-0-11" href="#__codelineno-0-11"></a> <span class="n">target</span><span class="p">:</span> <span class="n">ArrayLike</span> <span class="o">=</span> <span class="mf">1.0</span><span class="p">,</span>
|
||||
<a id="__codelineno-0-12" name="__codelineno-0-12" href="#__codelineno-0-12"></a><span class="p">)</span> <span class="o">-></span> <span class="n">NDArray</span><span class="p">[</span><span class="n">numpy</span><span class="o">.</span><span class="n">complexfloating</span><span class="p">]</span>
|
||||
</code></pre></div>
|
||||
|
||||
<div class="doc doc-contents ">
|
||||
|
||||
<p>Return the scalar multiplier that gives a desired temporal phasor response.</p>
|
||||
<p>The returned scale satisfies</p>
|
||||
<div class="highlight"><pre><span></span><code>temporal_phasor(scale * samples, omegas, dt, ...) == target
|
||||
</code></pre></div>
|
||||
<p>for each target frequency. The result keeps a leading frequency axis even
|
||||
when <code>omegas</code> is scalar.</p>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="doc doc-object doc-function">
|
||||
|
||||
|
||||
<h3 id="meanas.fdtd.phasor.real_injection_scale" class="doc doc-heading">
|
||||
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">real_injection_scale</span>
|
||||
|
||||
|
||||
<a href="#meanas.fdtd.phasor.real_injection_scale" class="headerlink" title="Permanent link">¶</a></h3>
|
||||
<div class="doc-signature highlight"><pre><span></span><code><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a><span class="nf">real_injection_scale</span><span class="p">(</span>
|
||||
<a id="__codelineno-0-2" name="__codelineno-0-2" href="#__codelineno-0-2"></a> <span class="n">samples</span><span class="p">:</span> <span class="n">ArrayLike</span><span class="p">,</span>
|
||||
<a id="__codelineno-0-3" name="__codelineno-0-3" href="#__codelineno-0-3"></a> <span class="n">omegas</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<a id="__codelineno-0-4" name="__codelineno-0-4" href="#__codelineno-0-4"></a> <span class="o">|</span> <span class="nb">complex</span>
|
||||
<a id="__codelineno-0-5" name="__codelineno-0-5" href="#__codelineno-0-5"></a> <span class="o">|</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">float</span> <span class="o">|</span> <span class="nb">complex</span><span class="p">]</span>
|
||||
<a id="__codelineno-0-6" name="__codelineno-0-6" href="#__codelineno-0-6"></a> <span class="o">|</span> <span class="n">NDArray</span><span class="p">,</span>
|
||||
<a id="__codelineno-0-7" name="__codelineno-0-7" href="#__codelineno-0-7"></a> <span class="n">dt</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
|
||||
<a id="__codelineno-0-8" name="__codelineno-0-8" href="#__codelineno-0-8"></a> <span class="o">*</span><span class="p">,</span>
|
||||
<a id="__codelineno-0-9" name="__codelineno-0-9" href="#__codelineno-0-9"></a> <span class="n">start_step</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
|
||||
<a id="__codelineno-0-10" name="__codelineno-0-10" href="#__codelineno-0-10"></a> <span class="n">offset_steps</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mf">0.0</span><span class="p">,</span>
|
||||
<a id="__codelineno-0-11" name="__codelineno-0-11" href="#__codelineno-0-11"></a> <span class="n">target</span><span class="p">:</span> <span class="n">ArrayLike</span> <span class="o">=</span> <span class="mf">1.0</span><span class="p">,</span>
|
||||
<a id="__codelineno-0-12" name="__codelineno-0-12" href="#__codelineno-0-12"></a><span class="p">)</span> <span class="o">-></span> <span class="n">NDArray</span><span class="p">[</span><span class="n">numpy</span><span class="o">.</span><span class="n">complexfloating</span><span class="p">]</span>
|
||||
</code></pre></div>
|
||||
|
||||
<div class="doc doc-contents ">
|
||||
|
||||
<p>Return the scale for a real-valued injection built from an analytic waveform.</p>
|
||||
<p>If the time-domain source is applied as</p>
|
||||
<div class="highlight"><pre><span></span><code>numpy.real(scale * samples[step])
|
||||
</code></pre></div>
|
||||
<p>then the desired positive-frequency phasor is obtained by compensating for
|
||||
the 1/2 factor between the real-valued source and its analytic component:</p>
|
||||
<div class="highlight"><pre><span></span><code>scale = 2 * target / temporal_phasor(samples, ...)
|
||||
</code></pre></div>
|
||||
<p>This helper normalizes only the intended positive-frequency component. Any
|
||||
residual negative-frequency leakage is controlled by the waveform design and
|
||||
the accumulation window.</p>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="doc doc-object doc-function">
|
||||
|
||||
|
||||
<h3 id="meanas.fdtd.phasor.reconstruct_real" class="doc doc-heading">
|
||||
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">reconstruct_real</span>
|
||||
|
||||
|
||||
<a href="#meanas.fdtd.phasor.reconstruct_real" class="headerlink" title="Permanent link">¶</a></h3>
|
||||
<div class="doc-signature highlight"><pre><span></span><code><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a><span class="nf">reconstruct_real</span><span class="p">(</span>
|
||||
<a id="__codelineno-0-2" name="__codelineno-0-2" href="#__codelineno-0-2"></a> <span class="n">phasors</span><span class="p">:</span> <span class="n">ArrayLike</span><span class="p">,</span>
|
||||
<a id="__codelineno-0-3" name="__codelineno-0-3" href="#__codelineno-0-3"></a> <span class="n">omegas</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<a id="__codelineno-0-4" name="__codelineno-0-4" href="#__codelineno-0-4"></a> <span class="o">|</span> <span class="nb">complex</span>
|
||||
<a id="__codelineno-0-5" name="__codelineno-0-5" href="#__codelineno-0-5"></a> <span class="o">|</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">float</span> <span class="o">|</span> <span class="nb">complex</span><span class="p">]</span>
|
||||
<a id="__codelineno-0-6" name="__codelineno-0-6" href="#__codelineno-0-6"></a> <span class="o">|</span> <span class="n">NDArray</span><span class="p">,</span>
|
||||
<a id="__codelineno-0-7" name="__codelineno-0-7" href="#__codelineno-0-7"></a> <span class="n">dt</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
|
||||
<a id="__codelineno-0-8" name="__codelineno-0-8" href="#__codelineno-0-8"></a> <span class="n">step</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
|
||||
<a id="__codelineno-0-9" name="__codelineno-0-9" href="#__codelineno-0-9"></a> <span class="o">*</span><span class="p">,</span>
|
||||
<a id="__codelineno-0-10" name="__codelineno-0-10" href="#__codelineno-0-10"></a> <span class="n">offset_steps</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mf">0.0</span><span class="p">,</span>
|
||||
<a id="__codelineno-0-11" name="__codelineno-0-11" href="#__codelineno-0-11"></a><span class="p">)</span> <span class="o">-></span> <span class="n">NDArray</span><span class="p">[</span><span class="n">numpy</span><span class="o">.</span><span class="n">floating</span><span class="p">]</span>
|
||||
</code></pre></div>
|
||||
|
||||
<div class="doc doc-contents ">
|
||||
|
||||
<p>Reconstruct a real-valued field snapshot from one or more phasors.</p>
|
||||
<p>The returned quantity is</p>
|
||||
<div class="highlight"><pre><span></span><code>real(phasor * exp(1j * omega * t_step))
|
||||
</code></pre></div>
|
||||
<p>where <code>t_step = (step + offset_steps) * dt</code>.</p>
|
||||
<p>For multi-frequency inputs, the leading frequency axis is preserved. For a
|
||||
scalar <code>omega</code>, callers may pass either <code>(1, *sample_shape)</code> or
|
||||
<code>sample_shape</code>; the return shape matches that choice.</p>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="doc doc-object doc-function">
|
||||
|
||||
|
||||
<h3 id="meanas.fdtd.phasor.accumulate_phasor_e" class="doc doc-heading">
|
||||
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">accumulate_phasor_e</span>
|
||||
|
||||
|
|
@ -3740,6 +4095,90 @@ factor was derived from a discrete sum that already includes <code>dt</code>, pa
|
|||
|
||||
</div>
|
||||
|
||||
<div class="doc doc-object doc-function">
|
||||
|
||||
|
||||
<h3 id="meanas.fdtd.phasor.reconstruct_real_e" class="doc doc-heading">
|
||||
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">reconstruct_real_e</span>
|
||||
|
||||
|
||||
<a href="#meanas.fdtd.phasor.reconstruct_real_e" class="headerlink" title="Permanent link">¶</a></h3>
|
||||
<div class="doc-signature highlight"><pre><span></span><code><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a><span class="nf">reconstruct_real_e</span><span class="p">(</span>
|
||||
<a id="__codelineno-0-2" name="__codelineno-0-2" href="#__codelineno-0-2"></a> <span class="n">phasors</span><span class="p">:</span> <span class="n">ArrayLike</span><span class="p">,</span>
|
||||
<a id="__codelineno-0-3" name="__codelineno-0-3" href="#__codelineno-0-3"></a> <span class="n">omegas</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<a id="__codelineno-0-4" name="__codelineno-0-4" href="#__codelineno-0-4"></a> <span class="o">|</span> <span class="nb">complex</span>
|
||||
<a id="__codelineno-0-5" name="__codelineno-0-5" href="#__codelineno-0-5"></a> <span class="o">|</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">float</span> <span class="o">|</span> <span class="nb">complex</span><span class="p">]</span>
|
||||
<a id="__codelineno-0-6" name="__codelineno-0-6" href="#__codelineno-0-6"></a> <span class="o">|</span> <span class="n">NDArray</span><span class="p">,</span>
|
||||
<a id="__codelineno-0-7" name="__codelineno-0-7" href="#__codelineno-0-7"></a> <span class="n">dt</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
|
||||
<a id="__codelineno-0-8" name="__codelineno-0-8" href="#__codelineno-0-8"></a> <span class="n">step</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
|
||||
<a id="__codelineno-0-9" name="__codelineno-0-9" href="#__codelineno-0-9"></a><span class="p">)</span> <span class="o">-></span> <span class="n">NDArray</span><span class="p">[</span><span class="n">numpy</span><span class="o">.</span><span class="n">floating</span><span class="p">]</span>
|
||||
</code></pre></div>
|
||||
|
||||
<div class="doc doc-contents ">
|
||||
|
||||
<p>Reconstruct a real E-field snapshot taken at integer timestep <code>step</code>.</p>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="doc doc-object doc-function">
|
||||
|
||||
|
||||
<h3 id="meanas.fdtd.phasor.reconstruct_real_h" class="doc doc-heading">
|
||||
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">reconstruct_real_h</span>
|
||||
|
||||
|
||||
<a href="#meanas.fdtd.phasor.reconstruct_real_h" class="headerlink" title="Permanent link">¶</a></h3>
|
||||
<div class="doc-signature highlight"><pre><span></span><code><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a><span class="nf">reconstruct_real_h</span><span class="p">(</span>
|
||||
<a id="__codelineno-0-2" name="__codelineno-0-2" href="#__codelineno-0-2"></a> <span class="n">phasors</span><span class="p">:</span> <span class="n">ArrayLike</span><span class="p">,</span>
|
||||
<a id="__codelineno-0-3" name="__codelineno-0-3" href="#__codelineno-0-3"></a> <span class="n">omegas</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<a id="__codelineno-0-4" name="__codelineno-0-4" href="#__codelineno-0-4"></a> <span class="o">|</span> <span class="nb">complex</span>
|
||||
<a id="__codelineno-0-5" name="__codelineno-0-5" href="#__codelineno-0-5"></a> <span class="o">|</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">float</span> <span class="o">|</span> <span class="nb">complex</span><span class="p">]</span>
|
||||
<a id="__codelineno-0-6" name="__codelineno-0-6" href="#__codelineno-0-6"></a> <span class="o">|</span> <span class="n">NDArray</span><span class="p">,</span>
|
||||
<a id="__codelineno-0-7" name="__codelineno-0-7" href="#__codelineno-0-7"></a> <span class="n">dt</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
|
||||
<a id="__codelineno-0-8" name="__codelineno-0-8" href="#__codelineno-0-8"></a> <span class="n">step</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
|
||||
<a id="__codelineno-0-9" name="__codelineno-0-9" href="#__codelineno-0-9"></a><span class="p">)</span> <span class="o">-></span> <span class="n">NDArray</span><span class="p">[</span><span class="n">numpy</span><span class="o">.</span><span class="n">floating</span><span class="p">]</span>
|
||||
</code></pre></div>
|
||||
|
||||
<div class="doc doc-contents ">
|
||||
|
||||
<p>Reconstruct a real H-field snapshot corresponding to <code>H_{step + 1/2}</code>.</p>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="doc doc-object doc-function">
|
||||
|
||||
|
||||
<h3 id="meanas.fdtd.phasor.reconstruct_real_j" class="doc doc-heading">
|
||||
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">reconstruct_real_j</span>
|
||||
|
||||
|
||||
<a href="#meanas.fdtd.phasor.reconstruct_real_j" class="headerlink" title="Permanent link">¶</a></h3>
|
||||
<div class="doc-signature highlight"><pre><span></span><code><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a><span class="nf">reconstruct_real_j</span><span class="p">(</span>
|
||||
<a id="__codelineno-0-2" name="__codelineno-0-2" href="#__codelineno-0-2"></a> <span class="n">phasors</span><span class="p">:</span> <span class="n">ArrayLike</span><span class="p">,</span>
|
||||
<a id="__codelineno-0-3" name="__codelineno-0-3" href="#__codelineno-0-3"></a> <span class="n">omegas</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<a id="__codelineno-0-4" name="__codelineno-0-4" href="#__codelineno-0-4"></a> <span class="o">|</span> <span class="nb">complex</span>
|
||||
<a id="__codelineno-0-5" name="__codelineno-0-5" href="#__codelineno-0-5"></a> <span class="o">|</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">float</span> <span class="o">|</span> <span class="nb">complex</span><span class="p">]</span>
|
||||
<a id="__codelineno-0-6" name="__codelineno-0-6" href="#__codelineno-0-6"></a> <span class="o">|</span> <span class="n">NDArray</span><span class="p">,</span>
|
||||
<a id="__codelineno-0-7" name="__codelineno-0-7" href="#__codelineno-0-7"></a> <span class="n">dt</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
|
||||
<a id="__codelineno-0-8" name="__codelineno-0-8" href="#__codelineno-0-8"></a> <span class="n">step</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
|
||||
<a id="__codelineno-0-9" name="__codelineno-0-9" href="#__codelineno-0-9"></a><span class="p">)</span> <span class="o">-></span> <span class="n">NDArray</span><span class="p">[</span><span class="n">numpy</span><span class="o">.</span><span class="n">floating</span><span class="p">]</span>
|
||||
</code></pre></div>
|
||||
|
||||
<div class="doc doc-contents ">
|
||||
|
||||
<p>Reconstruct a real current snapshot corresponding to <code>J_{step + 1/2}</code>.</p>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1402,132 +1402,144 @@ a structure with some (x, y) cross-section extending uniformly into the z dimens
|
|||
with a diagonal <span class="arithmatex">\(\epsilon\)</span> tensor, we have</p>
|
||||
<div class="arithmatex">\[
|
||||
\begin{aligned}
|
||||
\nabla \times \vec{E}(x, y, z) &= -\imath \omega \mu \vec{H} \\
|
||||
\nabla \times \vec{H}(x, y, z) &= \imath \omega \epsilon \vec{E} \\
|
||||
\vec{E}(x,y,z) &= (\vec{E}_t(x, y) + E_z(x, y)\vec{z}) e^{-\imath \beta z} \\
|
||||
\vec{H}(x,y,z) &= (\vec{H}_t(x, y) + H_z(x, y)\vec{z}) e^{-\imath \beta z} \\
|
||||
\nabla \times \vec{E}(x, y, z) &= -\imath \omega \mu \vec{H} \\
|
||||
\nabla \times \vec{H}(x, y, z) &= \imath \omega \epsilon \vec{E} \\
|
||||
\vec{E}(x,y,z) &= (\vec{E}_t(x, y) + E_z(x, y)\vec{z}) e^{-\imath \beta z} \\
|
||||
\vec{H}(x,y,z) &= (\vec{H}_t(x, y) + H_z(x, y)\vec{z}) e^{-\imath \beta z} \\
|
||||
\end{aligned}
|
||||
\]</div>
|
||||
|
||||
<p>Expanding the first two equations into vector components, we get</p>
|
||||
<div class="arithmatex">\[
|
||||
\begin{aligned}
|
||||
-\imath \omega \mu_{xx} H_x &= \partial_y E_z - \partial_z E_y \\
|
||||
-\imath \omega \mu_{yy} H_y &= \partial_z E_x - \partial_x E_z \\
|
||||
-\imath \omega \mu_{zz} H_z &= \partial_x E_y - \partial_y E_x \\
|
||||
\imath \omega \epsilon_{xx} E_x &= \partial_y H_z - \partial_z H_y \\
|
||||
\imath \omega \epsilon_{yy} E_y &= \partial_z H_x - \partial_x H_z \\
|
||||
\imath \omega \epsilon_{zz} E_z &= \partial_x H_y - \partial_y H_x \\
|
||||
-\imath \omega \mu_{xx} H_x &= \partial_y E_z - \partial_z E_y \\
|
||||
-\imath \omega \mu_{yy} H_y &= \partial_z E_x - \partial_x E_z \\
|
||||
-\imath \omega \mu_{zz} H_z &= \partial_x E_y - \partial_y E_x \\
|
||||
\imath \omega \epsilon_{xx} E_x &= \partial_y H_z - \partial_z H_y \\
|
||||
\imath \omega \epsilon_{yy} E_y &= \partial_z H_x - \partial_x H_z \\
|
||||
\imath \omega \epsilon_{zz} E_z &= \partial_x H_y - \partial_y H_x \\
|
||||
\end{aligned}
|
||||
\]</div>
|
||||
|
||||
<p>Substituting in our expressions for <span class="arithmatex">\(\vec{E}\)</span>, <span class="arithmatex">\(\vec{H}\)</span> and discretizing:</p>
|
||||
<div class="arithmatex">\[
|
||||
\begin{aligned}
|
||||
-\imath \omega \mu_{xx} H_x &= \tilde{\partial}_y E_z + \imath \beta E_y \\
|
||||
-\imath \omega \mu_{yy} H_y &= -\imath \beta E_x - \tilde{\partial}_x E_z \\
|
||||
-\imath \omega \mu_{zz} H_z &= \tilde{\partial}_x E_y - \tilde{\partial}_y E_x \\
|
||||
\imath \omega \epsilon_{xx} E_x &= \hat{\partial}_y H_z + \imath \beta H_y \\
|
||||
\imath \omega \epsilon_{yy} E_y &= -\imath \beta H_x - \hat{\partial}_x H_z \\
|
||||
\imath \omega \epsilon_{zz} E_z &= \hat{\partial}_x H_y - \hat{\partial}_y H_x \\
|
||||
-\imath \omega \mu_{xx} H_x &= \tilde{\partial}_y E_z + \imath \beta E_y \\
|
||||
-\imath \omega \mu_{yy} H_y &= -\imath \beta E_x - \tilde{\partial}_x E_z \\
|
||||
-\imath \omega \mu_{zz} H_z &= \tilde{\partial}_x E_y - \tilde{\partial}_y E_x \\
|
||||
\imath \omega \epsilon_{xx} E_x &= \hat{\partial}_y H_z + \imath \beta H_y \\
|
||||
\imath \omega \epsilon_{yy} E_y &= -\imath \beta H_x - \hat{\partial}_x H_z \\
|
||||
\imath \omega \epsilon_{zz} E_z &= \hat{\partial}_x H_y - \hat{\partial}_y H_x \\
|
||||
\end{aligned}
|
||||
\]</div>
|
||||
|
||||
<p>Rewrite the last three equations as</p>
|
||||
<div class="arithmatex">\[
|
||||
\begin{aligned}
|
||||
\imath \beta H_y &= \imath \omega \epsilon_{xx} E_x - \hat{\partial}_y H_z \\
|
||||
\imath \beta H_x &= -\imath \omega \epsilon_{yy} E_y - \hat{\partial}_x H_z \\
|
||||
\imath \omega E_z &= \frac{1}{\epsilon_{zz}} \hat{\partial}_x H_y - \frac{1}{\epsilon_{zz}} \hat{\partial}_y H_x \\
|
||||
\imath \beta H_y &= \imath \omega \epsilon_{xx} E_x - \hat{\partial}_y H_z \\
|
||||
\imath \beta H_x &= -\imath \omega \epsilon_{yy} E_y - \hat{\partial}_x H_z \\
|
||||
\imath \omega E_z &= \frac{1}{\epsilon_{zz}} \hat{\partial}_x H_y - \frac{1}{\epsilon_{zz}} \hat{\partial}_y H_x \\
|
||||
\end{aligned}
|
||||
\]</div>
|
||||
|
||||
<p>Now apply <span class="arithmatex">\(\imath \beta \tilde{\partial}_x\)</span> to the last equation,
|
||||
then substitute in for <span class="arithmatex">\(\imath \beta H_x\)</span> and <span class="arithmatex">\(\imath \beta H_y\)</span>:</p>
|
||||
<div class="arithmatex">\[
|
||||
\begin{aligned}
|
||||
\imath \beta \tilde{\partial}_x \imath \omega E_z &= \imath \beta \tilde{\partial}_x \frac{1}{\epsilon_{zz}} \hat{\partial}_x H_y
|
||||
\imath \beta \tilde{\partial}_x \imath \omega E_z &= \imath \beta \tilde{\partial}_x \frac{1}{\epsilon_{zz}} \hat{\partial}_x H_y
|
||||
- \imath \beta \tilde{\partial}_x \frac{1}{\epsilon_{zz}} \hat{\partial}_y H_x \\
|
||||
&= \tilde{\partial}_x \frac{1}{\epsilon_{zz}} \hat{\partial}_x ( \imath \omega \epsilon_{xx} E_x - \hat{\partial}_y H_z)
|
||||
&= \tilde{\partial}_x \frac{1}{\epsilon_{zz}} \hat{\partial}_x ( \imath \omega \epsilon_{xx} E_x - \hat{\partial}_y H_z)
|
||||
- \tilde{\partial}_x \frac{1}{\epsilon_{zz}} \hat{\partial}_y (-\imath \omega \epsilon_{yy} E_y - \hat{\partial}_x H_z) \\
|
||||
&= \tilde{\partial}_x \frac{1}{\epsilon_{zz}} \hat{\partial}_x ( \imath \omega \epsilon_{xx} E_x)
|
||||
&= \tilde{\partial}_x \frac{1}{\epsilon_{zz}} \hat{\partial}_x ( \imath \omega \epsilon_{xx} E_x)
|
||||
- \tilde{\partial}_x \frac{1}{\epsilon_{zz}} \hat{\partial}_y (-\imath \omega \epsilon_{yy} E_y) \\
|
||||
\imath \beta \tilde{\partial}_x E_z &= \tilde{\partial}_x \frac{1}{\epsilon_{zz}} \hat{\partial}_x (\epsilon_{xx} E_x)
|
||||
\imath \beta \tilde{\partial}_x E_z &= \tilde{\partial}_x \frac{1}{\epsilon_{zz}} \hat{\partial}_x (\epsilon_{xx} E_x)
|
||||
+ \tilde{\partial}_x \frac{1}{\epsilon_{zz}} \hat{\partial}_y (\epsilon_{yy} E_y) \\
|
||||
\end{aligned}
|
||||
\]</div>
|
||||
|
||||
<p>With a similar approach (but using <span class="arithmatex">\(\imath \beta \tilde{\partial}_y\)</span> instead), we can get</p>
|
||||
<div class="arithmatex">\[
|
||||
\begin{aligned}
|
||||
\imath \beta \tilde{\partial}_y E_z &= \tilde{\partial}_y \frac{1}{\epsilon_{zz}} \hat{\partial}_x (\epsilon_{xx} E_x)
|
||||
\imath \beta \tilde{\partial}_y E_z &= \tilde{\partial}_y \frac{1}{\epsilon_{zz}} \hat{\partial}_x (\epsilon_{xx} E_x)
|
||||
+ \tilde{\partial}_y \frac{1}{\epsilon_{zz}} \hat{\partial}_y (\epsilon_{yy} E_y) \\
|
||||
\end{aligned}
|
||||
\]</div>
|
||||
|
||||
<p>We can combine this equation for <span class="arithmatex">\(\imath \beta \tilde{\partial}_y E_z\)</span> with
|
||||
the unused <span class="arithmatex">\(\imath \omega \mu_{xx} H_x\)</span> and <span class="arithmatex">\(\imath \omega \mu_{yy} H_y\)</span> equations to get</p>
|
||||
<div class="arithmatex">\[
|
||||
\begin{aligned}
|
||||
-\imath \omega \mu_{xx} \imath \beta H_x &= -\beta^2 E_y + \imath \beta \tilde{\partial}_y E_z \\
|
||||
-\imath \omega \mu_{xx} \imath \beta H_x &= -\beta^2 E_y + \tilde{\partial}_y (
|
||||
-\imath \omega \mu_{xx} \imath \beta H_x &= -\beta^2 E_y + \imath \beta \tilde{\partial}_y E_z \\
|
||||
-\imath \omega \mu_{xx} \imath \beta H_x &= -\beta^2 E_y + \tilde{\partial}_y (
|
||||
\frac{1}{\epsilon_{zz}} \hat{\partial}_x (\epsilon_{xx} E_x)
|
||||
+ \frac{1}{\epsilon_{zz}} \hat{\partial}_y (\epsilon_{yy} E_y)
|
||||
)\\
|
||||
\end{aligned}
|
||||
\]</div>
|
||||
|
||||
<p>and</p>
|
||||
<div class="arithmatex">\[
|
||||
\begin{aligned}
|
||||
-\imath \omega \mu_{yy} \imath \beta H_y &= \beta^2 E_x - \imath \beta \tilde{\partial}_x E_z \\
|
||||
-\imath \omega \mu_{yy} \imath \beta H_y &= \beta^2 E_x - \tilde{\partial}_x (
|
||||
-\imath \omega \mu_{yy} \imath \beta H_y &= \beta^2 E_x - \imath \beta \tilde{\partial}_x E_z \\
|
||||
-\imath \omega \mu_{yy} \imath \beta H_y &= \beta^2 E_x - \tilde{\partial}_x (
|
||||
\frac{1}{\epsilon_{zz}} \hat{\partial}_x (\epsilon_{xx} E_x)
|
||||
+ \frac{1}{\epsilon_{zz}} \hat{\partial}_y (\epsilon_{yy} E_y)
|
||||
)\\
|
||||
\end{aligned}
|
||||
\]</div>
|
||||
|
||||
<p>However, based on our rewritten equation for <span class="arithmatex">\(\imath \beta H_x\)</span> and the so-far unused
|
||||
equation for <span class="arithmatex">\(\imath \omega \mu_{zz} H_z\)</span> we can also write</p>
|
||||
<div class="arithmatex">\[
|
||||
\begin{aligned}
|
||||
-\imath \omega \mu_{xx} (\imath \beta H_x) &= -\imath \omega \mu_{xx} (-\imath \omega \epsilon_{yy} E_y - \hat{\partial}_x H_z) \\
|
||||
&= -\omega^2 \mu_{xx} \epsilon_{yy} E_y + \imath \omega \mu_{xx} \hat{\partial}_x (
|
||||
-\imath \omega \mu_{xx} (\imath \beta H_x) &= -\imath \omega \mu_{xx} (-\imath \omega \epsilon_{yy} E_y - \hat{\partial}_x H_z) \\
|
||||
&= -\omega^2 \mu_{xx} \epsilon_{yy} E_y + \imath \omega \mu_{xx} \hat{\partial}_x (
|
||||
\frac{1}{-\imath \omega \mu_{zz}} (\tilde{\partial}_x E_y - \tilde{\partial}_y E_x)) \\
|
||||
&= -\omega^2 \mu_{xx} \epsilon_{yy} E_y
|
||||
&= -\omega^2 \mu_{xx} \epsilon_{yy} E_y
|
||||
-\mu_{xx} \hat{\partial}_x \frac{1}{\mu_{zz}} (\tilde{\partial}_x E_y - \tilde{\partial}_y E_x) \\
|
||||
\end{aligned}
|
||||
\]</div>
|
||||
|
||||
<p>and, similarly,</p>
|
||||
<div class="arithmatex">\[
|
||||
\begin{aligned}
|
||||
-\imath \omega \mu_{yy} (\imath \beta H_y) &= \omega^2 \mu_{yy} \epsilon_{xx} E_x
|
||||
-\imath \omega \mu_{yy} (\imath \beta H_y) &= \omega^2 \mu_{yy} \epsilon_{xx} E_x
|
||||
+\mu_{yy} \hat{\partial}_y \frac{1}{\mu_{zz}} (\tilde{\partial}_x E_y - \tilde{\partial}_y E_x) \\
|
||||
\end{aligned}
|
||||
\]</div>
|
||||
|
||||
<p>By combining both pairs of expressions, we get</p>
|
||||
<div class="arithmatex">\[
|
||||
\begin{aligned}
|
||||
\beta^2 E_x - \tilde{\partial}_x (
|
||||
\frac{1}{\epsilon_{zz}} \hat{\partial}_x (\epsilon_{xx} E_x)
|
||||
+ \frac{1}{\epsilon_{zz}} \hat{\partial}_y (\epsilon_{yy} E_y)
|
||||
) &= \omega^2 \mu_{yy} \epsilon_{xx} E_x
|
||||
) &= \omega^2 \mu_{yy} \epsilon_{xx} E_x
|
||||
+\mu_{yy} \hat{\partial}_y \frac{1}{\mu_{zz}} (\tilde{\partial}_x E_y - \tilde{\partial}_y E_x) \\
|
||||
-\beta^2 E_y + \tilde{\partial}_y (
|
||||
\frac{1}{\epsilon_{zz}} \hat{\partial}_x (\epsilon_{xx} E_x)
|
||||
+ \frac{1}{\epsilon_{zz}} \hat{\partial}_y (\epsilon_{yy} E_y)
|
||||
) &= -\omega^2 \mu_{xx} \epsilon_{yy} E_y
|
||||
) &= -\omega^2 \mu_{xx} \epsilon_{yy} E_y
|
||||
-\mu_{xx} \hat{\partial}_x \frac{1}{\mu_{zz}} (\tilde{\partial}_x E_y - \tilde{\partial}_y E_x) \\
|
||||
\end{aligned}
|
||||
\]</div>
|
||||
|
||||
<p>Using these, we can construct the eigenvalue problem</p>
|
||||
<div class="arithmatex">\[
|
||||
\beta^2 \begin{bmatrix} E_x \\
|
||||
E_y \end{bmatrix} =
|
||||
(\omega^2 \begin{bmatrix} \mu_{yy} \epsilon_{xx} & 0 \\
|
||||
0 & \mu_{xx} \epsilon_{yy} \end{bmatrix} +
|
||||
(\omega^2 \begin{bmatrix} \mu_{yy} \epsilon_{xx} & 0 \\
|
||||
0 & \mu_{xx} \epsilon_{yy} \end{bmatrix} +
|
||||
\begin{bmatrix} -\mu_{yy} \hat{\partial}_y \\
|
||||
\mu_{xx} \hat{\partial}_x \end{bmatrix} \mu_{zz}^{-1}
|
||||
\begin{bmatrix} -\tilde{\partial}_y & \tilde{\partial}_x \end{bmatrix} +
|
||||
\begin{bmatrix} -\tilde{\partial}_y & \tilde{\partial}_x \end{bmatrix} +
|
||||
\begin{bmatrix} \tilde{\partial}_x \\
|
||||
\tilde{\partial}_y \end{bmatrix} \epsilon_{zz}^{-1}
|
||||
\begin{bmatrix} \hat{\partial}_x \epsilon_{xx} & \hat{\partial}_y \epsilon_{yy} \end{bmatrix})
|
||||
\begin{bmatrix} \hat{\partial}_x \epsilon_{xx} & \hat{\partial}_y \epsilon_{yy} \end{bmatrix})
|
||||
\begin{bmatrix} E_x \\
|
||||
E_y \end{bmatrix}
|
||||
\]</div>
|
||||
|
||||
<p>In the literature, <span class="arithmatex">\(\beta\)</span> is usually used to denote the lossless/real part of the propagation constant,
|
||||
but in <code>meanas</code> it is allowed to be complex.</p>
|
||||
<p>An equivalent eigenvalue problem can be formed using the <span class="arithmatex">\(H_x\)</span> and <span class="arithmatex">\(H_y\)</span> fields, if those are more convenient.</p>
|
||||
|
|
@ -1580,15 +1592,16 @@ mu * [[-Dy], [Dx]] / mu * [-Dy, Dx] +
|
|||
<p>for use with a field vector of the form <code>cat([E_x, E_y])</code>.</p>
|
||||
<p>More precisely, the operator is</p>
|
||||
<div class="arithmatex">\[
|
||||
\omega^2 \begin{bmatrix} \mu_{yy} \epsilon_{xx} & 0 \\
|
||||
0 & \mu_{xx} \epsilon_{yy} \end{bmatrix} +
|
||||
\omega^2 \begin{bmatrix} \mu_{yy} \epsilon_{xx} & 0 \\
|
||||
0 & \mu_{xx} \epsilon_{yy} \end{bmatrix} +
|
||||
\begin{bmatrix} -\mu_{yy} \hat{\partial}_y \\
|
||||
\mu_{xx} \hat{\partial}_x \end{bmatrix} \mu_{zz}^{-1}
|
||||
\begin{bmatrix} -\tilde{\partial}_y & \tilde{\partial}_x \end{bmatrix} +
|
||||
\begin{bmatrix} -\tilde{\partial}_y & \tilde{\partial}_x \end{bmatrix} +
|
||||
\begin{bmatrix} \tilde{\partial}_x \\
|
||||
\tilde{\partial}_y \end{bmatrix} \epsilon_{zz}^{-1}
|
||||
\begin{bmatrix} \hat{\partial}_x \epsilon_{xx} & \hat{\partial}_y \epsilon_{yy} \end{bmatrix}
|
||||
\begin{bmatrix} \hat{\partial}_x \epsilon_{xx} & \hat{\partial}_y \epsilon_{yy} \end{bmatrix}
|
||||
\]</div>
|
||||
|
||||
<p><span class="arithmatex">\(\tilde{\partial}_x\)</span> and <span class="arithmatex">\(\hat{\partial}_x\)</span> are the forward and backward derivatives along x,
|
||||
and each <span class="arithmatex">\(\epsilon_{xx}\)</span>, <span class="arithmatex">\(\mu_{yy}\)</span>, etc. is a diagonal matrix containing the vectorized material
|
||||
property distribution.</p>
|
||||
|
|
@ -1735,15 +1748,16 @@ epsilon * [[-Dy], [Dx]] / epsilon * [-Dy, Dx] +
|
|||
<p>for use with a field vector of the form <code>cat([H_x, H_y])</code>.</p>
|
||||
<p>More precisely, the operator is</p>
|
||||
<div class="arithmatex">\[
|
||||
\omega^2 \begin{bmatrix} \epsilon_{yy} \mu_{xx} & 0 \\
|
||||
0 & \epsilon_{xx} \mu_{yy} \end{bmatrix} +
|
||||
\omega^2 \begin{bmatrix} \epsilon_{yy} \mu_{xx} & 0 \\
|
||||
0 & \epsilon_{xx} \mu_{yy} \end{bmatrix} +
|
||||
\begin{bmatrix} -\epsilon_{yy} \tilde{\partial}_y \\
|
||||
\epsilon_{xx} \tilde{\partial}_x \end{bmatrix} \epsilon_{zz}^{-1}
|
||||
\begin{bmatrix} -\hat{\partial}_y & \hat{\partial}_x \end{bmatrix} +
|
||||
\begin{bmatrix} -\hat{\partial}_y & \hat{\partial}_x \end{bmatrix} +
|
||||
\begin{bmatrix} \hat{\partial}_x \\
|
||||
\hat{\partial}_y \end{bmatrix} \mu_{zz}^{-1}
|
||||
\begin{bmatrix} \tilde{\partial}_x \mu_{xx} & \tilde{\partial}_y \mu_{yy} \end{bmatrix}
|
||||
\begin{bmatrix} \tilde{\partial}_x \mu_{xx} & \tilde{\partial}_y \mu_{yy} \end{bmatrix}
|
||||
\]</div>
|
||||
|
||||
<p><span class="arithmatex">\(\tilde{\partial}_x\)</span> and <span class="arithmatex">\(\hat{\partial}_x\)</span> are the forward and backward derivatives along x,
|
||||
and each <span class="arithmatex">\(\epsilon_{xx}\)</span>, <span class="arithmatex">\(\mu_{yy}\)</span>, etc. is a diagonal matrix containing the vectorized material
|
||||
property distribution.</p>
|
||||
|
|
@ -2066,6 +2080,7 @@ and <code>exy2h(...)</code>, then normalizes them to unit forward power using
|
|||
<div class="arithmatex">\[
|
||||
\Re\left[\mathrm{inner\_product}(e, h, \mathrm{conj\_h}=True)\right] = 1,
|
||||
\]</div>
|
||||
|
||||
<p>so the returned fields represent a unit-power forward mode under the
|
||||
discrete Yee-grid Poynting inner product.</p>
|
||||
</details>
|
||||
|
|
@ -2721,21 +2736,23 @@ identical representatives for nearly symmetric modes.</p>
|
|||
<div class="arithmatex">\[
|
||||
\imath \omega \epsilon_{zz} E_z = \hat{\partial}_x H_y - \hat{\partial}_y H_x \\
|
||||
\]</div>
|
||||
|
||||
<p>as well as the intermediate equations</p>
|
||||
<div class="arithmatex">\[
|
||||
\begin{aligned}
|
||||
\imath \beta H_y &= \imath \omega \epsilon_{xx} E_x - \hat{\partial}_y H_z \\
|
||||
\imath \beta H_x &= -\imath \omega \epsilon_{yy} E_y - \hat{\partial}_x H_z \\
|
||||
\imath \beta H_y &= \imath \omega \epsilon_{xx} E_x - \hat{\partial}_y H_z \\
|
||||
\imath \beta H_x &= -\imath \omega \epsilon_{yy} E_y - \hat{\partial}_x H_z \\
|
||||
\end{aligned}
|
||||
\]</div>
|
||||
|
||||
<p>Combining these, we get</p>
|
||||
<div class="arithmatex">\[
|
||||
\begin{aligned}
|
||||
E_z &= \frac{1}{- \omega \beta \epsilon_{zz}} ((
|
||||
E_z &= \frac{1}{- \omega \beta \epsilon_{zz}} ((
|
||||
\hat{\partial}_y \hat{\partial}_x H_z
|
||||
-\hat{\partial}_x \hat{\partial}_y H_z)
|
||||
+ \imath \omega (\hat{\partial}_x \epsilon_{xx} E_x + \hat{\partial}_y \epsilon{yy} E_y))
|
||||
&= \frac{1}{\imath \beta \epsilon_{zz}} (\hat{\partial}_x \epsilon_{xx} E_x + \hat{\partial}_y \epsilon{yy} E_y)
|
||||
&= \frac{1}{\imath \beta \epsilon_{zz}} (\hat{\partial}_x \epsilon_{xx} E_x + \hat{\partial}_y \epsilon{yy} E_y)
|
||||
\end{aligned}
|
||||
\]</div>
|
||||
|
||||
|
|
@ -3655,9 +3672,11 @@ E_z &= \frac{1}{- \omega \beta \epsilon_{zz}} ((
|
|||
<p>The output is a vector of the same size as <code>vec(epsilon)</code>, with each element specifying the
|
||||
sensitivity of <code>wavenumber</code> to changes in the corresponding element in <code>vec(epsilon)</code>, i.e.</p>
|
||||
<div class="arithmatex">\[ sens_{i} = \frac{\partial\beta}{\partial\epsilon_i} \]</div>
|
||||
|
||||
<p>An adjoint approach is used to calculate the sensitivity; the derivation is provided here:</p>
|
||||
<p>Starting with the eigenvalue equation</p>
|
||||
<div class="arithmatex">\[ \beta^2 E_{xy} = A_E E_{xy} \]</div>
|
||||
|
||||
<p>where <span class="arithmatex">\(A_E\)</span> is the waveguide operator from <code>operator_e()</code>, and <span class="arithmatex">\(E_{xy} = \begin{bmatrix} E_x \\
|
||||
E_y \end{bmatrix}\)</span>,
|
||||
we can differentiate with respect to one of the <span class="arithmatex">\(\epsilon\)</span> elements (i.e. at one Yee grid point), <span class="arithmatex">\(\epsilon_i\)</span>:</p>
|
||||
|
|
@ -3665,11 +3684,13 @@ we can differentiate with respect to one of the <span class="arithmatex">\(\epsi
|
|||
(2 \beta) \partial_{\epsilon_i}(\beta) E_{xy} + \beta^2 \partial_{\epsilon_i} E_{xy}
|
||||
= \partial_{\epsilon_i}(A_E) E_{xy} + A_E \partial_{\epsilon_i} E_{xy}
|
||||
\]</div>
|
||||
|
||||
<p>We then multiply by <span class="arithmatex">\(H_{yx}^\star = \begin{bmatrix}H_y^\star \\ -H_x^\star \end{bmatrix}\)</span> from the left:</p>
|
||||
<div class="arithmatex">\[
|
||||
(2 \beta) \partial_{\epsilon_i}(\beta) H_{yx}^\star E_{xy} + \beta^2 H_{yx}^\star \partial_{\epsilon_i} E_{xy}
|
||||
= H_{yx}^\star \partial_{\epsilon_i}(A_E) E_{xy} + H_{yx}^\star A_E \partial_{\epsilon_i} E_{xy}
|
||||
\]</div>
|
||||
|
||||
<p>However, <span class="arithmatex">\(H_{yx}^\star\)</span> is actually a left-eigenvector of <span class="arithmatex">\(A_E\)</span>. This can be verified by inspecting
|
||||
the form of <code>operator_h</code> (<span class="arithmatex">\(A_H\)</span>) and comparing its conjugate transpose to <code>operator_e</code> (<span class="arithmatex">\(A_E\)</span>). Also, note
|
||||
<span class="arithmatex">\(H_{yx}^\star \cdot E_{xy} = H^\star \times E\)</span> recalls the mode orthogonality relation. See doi:10.5194/ars-9-85-201
|
||||
|
|
@ -3677,11 +3698,13 @@ for a similar approach. Therefore,</p>
|
|||
<div class="arithmatex">\[
|
||||
H_{yx}^\star A_E \partial_{\epsilon_i} E_{xy} = \beta^2 H_{yx}^\star \partial_{\epsilon_i} E_{xy}
|
||||
\]</div>
|
||||
|
||||
<p>and we can simplify to</p>
|
||||
<div class="arithmatex">\[
|
||||
\partial_{\epsilon_i}(\beta)
|
||||
= \frac{1}{2 \beta} \frac{H_{yx}^\star \partial_{\epsilon_i}(A_E) E_{xy} }{H_{yx}^\star E_{xy}}
|
||||
\]</div>
|
||||
|
||||
<p>This expression can be quickly calculated for all <span class="arithmatex">\(i\)</span> by writing out the various terms of
|
||||
<span class="arithmatex">\(\partial_{\epsilon_i} A_E\)</span> and recognizing that the vector-matrix-vector products (i.e. scalars)
|
||||
<span class="arithmatex">\(sens_i = \vec{v}_{left} \partial_{\epsilon_i} (\epsilon_{xyz}) \vec{v}_{right}\)</span>, indexed by <span class="arithmatex">\(i\)</span>, can be expressed as
|
||||
|
|
@ -4161,6 +4184,7 @@ longitudinal Poynting flux,</p>
|
|||
<div class="arithmatex">\[
|
||||
\frac{1}{2}\int (E_x H_y - E_y H_x) \, dx \, dy
|
||||
\]</div>
|
||||
|
||||
<p>with the Yee-grid staggering and optional propagation-phase adjustment used
|
||||
by the waveguide helpers in this module.</p>
|
||||
|
||||
|
|
@ -4866,6 +4890,7 @@ same sign convention used elsewhere in the package:</p>
|
|||
<div class="arithmatex">\[
|
||||
\sum \mathrm{overlap\_e} \; E_\mathrm{other}^*
|
||||
\]</div>
|
||||
|
||||
<p>where the sum is over the full Yee-grid field storage.</p>
|
||||
<p>The construction uses a two-cell window immediately upstream of the selected
|
||||
slice:</p>
|
||||
|
|
@ -4881,6 +4906,7 @@ overlap relation involving</p>
|
|||
<div class="arithmatex">\[
|
||||
\int ((E \times H_\mathrm{mode}) + (E_\mathrm{mode} \times H)) \cdot dn.
|
||||
\]</div>
|
||||
|
||||
<p>E x H_mode + E_mode x H
|
||||
-> Ex Hmy - EyHmx + Emx Hy - Emy Hx (Z-prop)
|
||||
Ex we/B Emx + Ex i/B dy Hmz - Ey (-we/B Emy) - Ey i/B dx Hmz
|
||||
|
|
@ -5219,6 +5245,7 @@ along the propagation axis and applies the phase factor</p>
|
|||
<div class="arithmatex">\[
|
||||
e^{-i \, \mathrm{polarity} \, wavenumber \, \Delta z}
|
||||
\]</div>
|
||||
|
||||
<p>to each copied slice.</p>
|
||||
</details>
|
||||
|
||||
|
|
@ -5254,11 +5281,13 @@ and the fields are assumed to have the form</p>
|
|||
<div class="arithmatex">\[
|
||||
\vec{E}(r, y, \theta), \vec{H}(r, y, \theta) \propto e^{-\imath m \theta},
|
||||
\]</div>
|
||||
|
||||
<p>where <code>m</code> is the angular wavenumber returned by <code>solve_mode(s)</code>. It is often
|
||||
convenient to introduce the corresponding linear wavenumber</p>
|
||||
<div class="arithmatex">\[
|
||||
\beta = \frac{m}{r_{\min}},
|
||||
\]</div>
|
||||
|
||||
<p>so that the cylindrical problem resembles the straight-waveguide problem with
|
||||
additional metric factors.</p>
|
||||
<p>Those metric factors live on the staggered radial Yee grids. If the left edge of
|
||||
|
|
@ -5266,33 +5295,36 @@ the computational window is at <code>r = r_{\min}</code>, define the electric-gr
|
|||
magnetic-grid radial sample locations by</p>
|
||||
<div class="arithmatex">\[
|
||||
\begin{aligned}
|
||||
r_a(n) &= r_{\min} + \sum_{j \le n} \Delta r_{e, j}, \\
|
||||
r_b\!\left(n + \tfrac{1}{2}\right) &= r_{\min} + \tfrac{1}{2}\Delta r_{e, n}
|
||||
+ \sum_{j < n} \Delta r_{h, j},
|
||||
r_a(n) &= r_{\min} + \sum_{j \le n} \Delta r_{e, j}, \\
|
||||
r_b\!\left(n + \tfrac{1}{2}\right) &= r_{\min} + \tfrac{1}{2}\Delta r_{e, n}
|
||||
+ \sum_{j < n} \Delta r_{h, j},
|
||||
\end{aligned}
|
||||
\]</div>
|
||||
|
||||
<p>and from them the diagonal metric matrices</p>
|
||||
<div class="arithmatex">\[
|
||||
\begin{aligned}
|
||||
T_a &= \operatorname{diag}(r_a / r_{\min}), \\
|
||||
T_b &= \operatorname{diag}(r_b / r_{\min}).
|
||||
T_a &= \operatorname{diag}(r_a / r_{\min}), \\
|
||||
T_b &= \operatorname{diag}(r_b / r_{\min}).
|
||||
\end{aligned}
|
||||
\]</div>
|
||||
|
||||
<p>With the same forward/backward derivative notation used in <code>waveguide_2d</code>, the
|
||||
coordinate-transformed discrete curl equations used here are</p>
|
||||
<div class="arithmatex">\[
|
||||
\begin{aligned}
|
||||
-\imath \omega \mu_{rr} H_r &= \tilde{\partial}_y E_z + \imath \beta T_a^{-1} E_y, \\
|
||||
-\imath \omega \mu_{yy} H_y &= -\imath \beta T_b^{-1} E_r
|
||||
-\imath \omega \mu_{rr} H_r &= \tilde{\partial}_y E_z + \imath \beta T_a^{-1} E_y, \\
|
||||
-\imath \omega \mu_{yy} H_y &= -\imath \beta T_b^{-1} E_r
|
||||
- T_b^{-1} \tilde{\partial}_r (T_a E_z), \\
|
||||
-\imath \omega \mu_{zz} H_z &= \tilde{\partial}_r E_y - \tilde{\partial}_y E_r, \\
|
||||
\imath \beta H_y &= -\imath \omega T_b \epsilon_{rr} E_r - T_b \hat{\partial}_y H_z, \\
|
||||
\imath \beta H_r &= \imath \omega T_a \epsilon_{yy} E_y
|
||||
-\imath \omega \mu_{zz} H_z &= \tilde{\partial}_r E_y - \tilde{\partial}_y E_r, \\
|
||||
\imath \beta H_y &= -\imath \omega T_b \epsilon_{rr} E_r - T_b \hat{\partial}_y H_z, \\
|
||||
\imath \beta H_r &= \imath \omega T_a \epsilon_{yy} E_y
|
||||
- T_b T_a^{-1} \hat{\partial}_r (T_b H_z), \\
|
||||
\imath \omega E_z &= T_a \epsilon_{zz}^{-1}
|
||||
\imath \omega E_z &= T_a \epsilon_{zz}^{-1}
|
||||
\left(\hat{\partial}_r H_y - \hat{\partial}_y H_r\right).
|
||||
\end{aligned}
|
||||
\]</div>
|
||||
|
||||
<p>The first three equations are the cylindrical analogue of the straight-guide
|
||||
relations for <code>H_r</code>, <code>H_y</code>, and <code>H_z</code>. The next two are the metric-weighted
|
||||
versions of the straight-guide identities for <code>\imath \beta H_y</code> and
|
||||
|
|
@ -5306,6 +5338,7 @@ and then eliminate <code>H_z</code> with</p>
|
|||
H_z = \frac{1}{-\imath \omega \mu_{zz}}
|
||||
\left(\tilde{\partial}_r E_y - \tilde{\partial}_y E_r\right).
|
||||
\]</div>
|
||||
|
||||
<p>This yields the transverse electric eigenproblem implemented by
|
||||
<code>cylindrical_operator(...)</code>:</p>
|
||||
<div class="arithmatex">\[
|
||||
|
|
@ -5315,8 +5348,8 @@ H_z = \frac{1}{-\imath \omega \mu_{zz}}
|
|||
\left(
|
||||
\omega^2
|
||||
\begin{bmatrix}
|
||||
T_b^2 \mu_{yy} \epsilon_{xx} & 0 \\
|
||||
0 & T_a^2 \mu_{xx} \epsilon_{yy}
|
||||
T_b^2 \mu_{yy} \epsilon_{xx} & 0 \\
|
||||
0 & T_a^2 \mu_{xx} \epsilon_{yy}
|
||||
\end{bmatrix}
|
||||
+
|
||||
\begin{bmatrix}
|
||||
|
|
@ -5325,7 +5358,7 @@ T_b^2 \mu_{yy} \epsilon_{xx} & 0 \\
|
|||
\end{bmatrix}
|
||||
T_b \mu_{zz}^{-1}
|
||||
\begin{bmatrix}
|
||||
-\tilde{\partial}_y & \tilde{\partial}_x
|
||||
-\tilde{\partial}_y & \tilde{\partial}_x
|
||||
\end{bmatrix}
|
||||
+
|
||||
\begin{bmatrix}
|
||||
|
|
@ -5334,12 +5367,13 @@ T_b \mu_{zz}^{-1}
|
|||
\end{bmatrix}
|
||||
T_a \epsilon_{zz}^{-1}
|
||||
\begin{bmatrix}
|
||||
\hat{\partial}_x T_b \epsilon_{xx} &
|
||||
\hat{\partial}_x T_b \epsilon_{xx} &
|
||||
\hat{\partial}_y T_a \epsilon_{yy}
|
||||
\end{bmatrix}
|
||||
\right)
|
||||
\begin{bmatrix} E_r \\ E_y \end{bmatrix}.
|
||||
\]</div>
|
||||
|
||||
<p>Since <code>\beta = m / r_{\min}</code>, the solver implemented in this file returns the
|
||||
angular wavenumber <code>m</code>, while the operator itself is most naturally written in
|
||||
terms of the linear quantity <code>\beta</code>. The helpers below reconstruct the full
|
||||
|
|
@ -5389,17 +5423,18 @@ product used by <code>waveguide_2d</code>.</p>
|
|||
|
||||
<p>Cylindrical coordinate waveguide operator of the form</p>
|
||||
<div class="arithmatex">\[
|
||||
(\omega^2 \begin{bmatrix} T_b T_b \mu_{yy} \epsilon_{xx} & 0 \\
|
||||
0 & T_a T_a \mu_{xx} \epsilon_{yy} \end{bmatrix} +
|
||||
(\omega^2 \begin{bmatrix} T_b T_b \mu_{yy} \epsilon_{xx} & 0 \\
|
||||
0 & T_a T_a \mu_{xx} \epsilon_{yy} \end{bmatrix} +
|
||||
\begin{bmatrix} -T_b \mu_{yy} \hat{\partial}_y \\
|
||||
T_a \mu_{xx} \hat{\partial}_x \end{bmatrix} T_b \mu_{zz}^{-1}
|
||||
\begin{bmatrix} -\tilde{\partial}_y & \tilde{\partial}_x \end{bmatrix} +
|
||||
\begin{bmatrix} -\tilde{\partial}_y & \tilde{\partial}_x \end{bmatrix} +
|
||||
\begin{bmatrix} \tilde{\partial}_x \\
|
||||
\tilde{\partial}_y \end{bmatrix} T_a \epsilon_{zz}^{-1}
|
||||
\begin{bmatrix} \hat{\partial}_x T_b \epsilon_{xx} & \hat{\partial}_y T_a \epsilon_{yy} \end{bmatrix})
|
||||
\begin{bmatrix} \hat{\partial}_x T_b \epsilon_{xx} & \hat{\partial}_y T_a \epsilon_{yy} \end{bmatrix})
|
||||
\begin{bmatrix} E_r \\
|
||||
E_y \end{bmatrix}
|
||||
\]</div>
|
||||
|
||||
<p>for use with a field vector of the form <code>[E_r, E_y]</code>.</p>
|
||||
<p>This operator can be used to form an eigenvalue problem of the form
|
||||
A @ [E_r, E_y] = beta**2 * [E_r, E_y]</p>
|
||||
|
|
@ -6288,15 +6323,15 @@ from E_r and E_y in order to then calculate E_z.</p>
|
|||
|
||||
<p>Returns an operator which, when applied to a vectorized E eigenfield, produces
|
||||
the vectorized H eigenfield.</p>
|
||||
<p>This operator is created directly from the initial coordinate-transformed equations:
|
||||
$$
|
||||
<p>This operator is created directly from the initial coordinate-transformed equations:</p>
|
||||
<div class="arithmatex">\[
|
||||
\begin{aligned}
|
||||
-\imath \omega \mu_{rr} H_r &= \tilde{\partial}<em yy="yy">y E_z + \imath \beta T_a^{-1} E_y, \
|
||||
-\imath \omega \mu</em> E_r
|
||||
- T_b^{-1} \tilde{\partial}} H_y &= -\imath \beta T_b^{-1<em zz="zz">r (T_a E_z), \
|
||||
-\imath \omega \mu</em>_y E_r,
|
||||
-\imath \omega \mu_{rr} H_r &= \tilde{\partial}_y E_z + \imath \beta T_a^{-1} E_y, \\
|
||||
-\imath \omega \mu_{yy} H_y &= -\imath \beta T_b^{-1} E_r
|
||||
- T_b^{-1} \tilde{\partial}_r (T_a E_z), \\
|
||||
-\imath \omega \mu_{zz} H_z &= \tilde{\partial}_r E_y - \tilde{\partial}_y E_r,
|
||||
\end{aligned}
|
||||
$$} H_z &= \tilde{\partial}_r E_y - \tilde{\partial</p>
|
||||
\]</div>
|
||||
|
||||
|
||||
<p><span class="doc-section-title">Parameters:</span></p>
|
||||
|
|
@ -6745,6 +6780,7 @@ enforces unit forward power under the discrete inner product</p>
|
|||
<div class="arithmatex">\[
|
||||
\frac{1}{2}\int (E_r H_y^* - E_y H_r^*) \, dr \, dy.
|
||||
\]</div>
|
||||
|
||||
<p>The angular wavenumber <code>m</code> is first converted into the full three-component
|
||||
fields, then the overall complex phase and sign are fixed so the result is
|
||||
reproducible for symmetric modes.</p>
|
||||
|
|
|
|||
20
index.html
20
index.html
|
|
@ -647,10 +647,26 @@ conventions.</p>
|
|||
<p>For most users, the tracked examples under <code>examples/</code> are the right entry
|
||||
point. They show the intended combinations of tools for solving complete
|
||||
problems.</p>
|
||||
<p>Relevant starting examples:</p>
|
||||
<ul>
|
||||
<li><code>examples/fdtd.py</code> for broadband pulse excitation and phasor extraction</li>
|
||||
<li><code>examples/waveguide.py</code> for guided phasor-domain FDTD/FDFD comparison</li>
|
||||
<li><code>examples/waveguide_real.py</code> for real-valued continuous-wave FDTD compared
|
||||
against real fields reconstructed from an FDFD solution, including guided-core,
|
||||
mode-weighted, and guided-mode / residual comparisons</li>
|
||||
<li><code>examples/fdfd.py</code> for direct frequency-domain waveguide excitation</li>
|
||||
</ul>
|
||||
<p>For solver equivalence, prefer the phasor-based examples first. They compare
|
||||
the extracted <code>+\omega</code> content of the FDTD run directly against the FDFD
|
||||
solution and are the main accuracy benchmarks in the test suite.</p>
|
||||
<p><code>examples/waveguide_real.py</code> answers a different, stricter question: how well a
|
||||
late raw real snapshot matches <code>Re(E_\omega e^{i\omega t})</code> on a monitor plane.
|
||||
That diagnostic is useful, but it also includes orthogonal residual structure
|
||||
that the phasor comparison intentionally filters out.</p>
|
||||
<p>The API pages are better read as a toolbox map and derivation reference:</p>
|
||||
<ul>
|
||||
<li>Use the <a href="api/fdtd/">FDTD API</a> for time-domain stepping, CPML, and phasor
|
||||
extraction.</li>
|
||||
<li>Use the <a href="api/fdtd/">FDTD API</a> for time-domain stepping, CPML, phasor
|
||||
extraction, and real-field reconstruction from FDFD phasors.</li>
|
||||
<li>Use the <a href="api/fdfd/">FDFD API</a> for driven frequency-domain solves and sparse
|
||||
operator algebra.</li>
|
||||
<li>Use the <a href="api/waveguides/">Waveguide API</a> for mode solving, port sources,
|
||||
|
|
|
|||
BIN
objects.inv
BIN
objects.inv
Binary file not shown.
File diff suppressed because it is too large
Load diff
File diff suppressed because one or more lines are too long
701
standalone.html
701
standalone.html
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue