[phasor] add temporal_phasor and temporal_phasor_scale
This commit is contained in:
parent
318c43d62d
commit
c0b41752e1
6 changed files with 323 additions and 67 deletions
|
|
@ -139,8 +139,8 @@ def main():
|
|||
print(f'{grid.shape=}')
|
||||
|
||||
dt = dx * 0.99 / numpy.sqrt(3)
|
||||
ee = numpy.zeros_like(epsilon, dtype=dtype)
|
||||
hh = numpy.zeros_like(epsilon, dtype=dtype)
|
||||
ee = numpy.zeros_like(epsilon, dtype=complex)
|
||||
hh = numpy.zeros_like(epsilon, dtype=complex)
|
||||
|
||||
dxes = [grid.dxyz, grid.autoshifted_dxyz()]
|
||||
|
||||
|
|
@ -149,25 +149,25 @@ def main():
|
|||
[cpml_params(axis=dd, polarity=pp, dt=dt, thickness=pml_thickness, epsilon_eff=n_air ** 2)
|
||||
for pp in (-1, +1)]
|
||||
for dd in range(3)]
|
||||
update_E, update_H = updates_with_cpml(cpml_params=pml_params, dt=dt, dxes=dxes, epsilon=epsilon)
|
||||
update_E, update_H = updates_with_cpml(cpml_params=pml_params, dt=dt, dxes=dxes, epsilon=epsilon, dtype=complex)
|
||||
|
||||
# sample_interval = numpy.floor(1 / (2 * 1 / wl * dt)).astype(int)
|
||||
# print(f'Save time interval would be {sample_interval} * dt = {sample_interval * dt:3g}')
|
||||
|
||||
|
||||
# Source parameters and function. The pulse normalization is kept outside
|
||||
# accumulate_phasor(); the helper only performs the Fourier sum.
|
||||
source_phasor, delay = gaussian_packet(wl=wl, dwl=100, dt=dt, turn_on=1e-5)
|
||||
aa, cc, ss = source_phasor(numpy.arange(max_t))
|
||||
srca_real = aa * cc
|
||||
src_maxt = numpy.argwhere(numpy.diff(aa < 1e-5))[-1]
|
||||
assert aa[src_maxt - 1] >= 1e-5
|
||||
phasor_norm = dt / (aa * cc * cc).sum()
|
||||
|
||||
Jph = numpy.zeros_like(epsilon, dtype=complex)
|
||||
Jph[1, *(grid.shape // 2)] = epsilon[1, *(grid.shape // 2)]
|
||||
# Build the pulse directly at the current half-steps and normalize that
|
||||
# scalar waveform so its extracted temporal phasor is exactly 1 at omega.
|
||||
source_phasor, _delay = gaussian_packet(wl=wl, dwl=100, dt=dt, turn_on=1e-5)
|
||||
aa, cc, ss = source_phasor(numpy.arange(max_t) + 0.5)
|
||||
source_waveform = aa * (cc + 1j * ss)
|
||||
omega = 2 * numpy.pi / wl
|
||||
pulse_scale = fdtd.temporal_phasor_scale(source_waveform, omega, dt, offset_steps=0.5)[0]
|
||||
|
||||
j_source = numpy.zeros_like(epsilon, dtype=complex)
|
||||
j_source[1, *(grid.shape // 2)] = epsilon[1, *(grid.shape // 2)]
|
||||
jph = numpy.zeros((1, *epsilon.shape), dtype=complex)
|
||||
eph = numpy.zeros((1, *epsilon.shape), dtype=complex)
|
||||
hph = numpy.zeros((1, *epsilon.shape), dtype=complex)
|
||||
|
||||
# #### Run a bunch of iterations ####
|
||||
output_file = h5py.File('simulation_output.h5', 'w')
|
||||
|
|
@ -175,10 +175,10 @@ def main():
|
|||
for tt in range(max_t):
|
||||
update_E(ee, hh, epsilon)
|
||||
|
||||
if tt < src_maxt:
|
||||
# Electric-current injection uses E -= dt * J / epsilon, which is
|
||||
# the same sign convention used by the matching FDFD right-hand side.
|
||||
ee[1, *(grid.shape // 2)] -= srca_real[tt]
|
||||
# Electric-current injection uses E -= dt * J / epsilon, which is the
|
||||
# same sign convention used by the matching FDFD right-hand side.
|
||||
j_step = pulse_scale * source_waveform[tt] * j_source
|
||||
ee -= dt * j_step / epsilon
|
||||
update_H(ee, hh)
|
||||
|
||||
avg_rate = (tt + 1) / (time.perf_counter() - start)
|
||||
|
|
@ -186,7 +186,7 @@ def main():
|
|||
|
||||
if tt % 200 == 0:
|
||||
print(f'iteration {tt}: average {avg_rate} iterations per sec')
|
||||
E_energy_sum = (ee * ee * epsilon).sum()
|
||||
E_energy_sum = (ee.conj() * ee * epsilon).sum().real
|
||||
print(f'{E_energy_sum=}')
|
||||
|
||||
# Save field slices
|
||||
|
|
@ -194,21 +194,12 @@ def main():
|
|||
print(f'saving E-field at iteration {tt}')
|
||||
output_file[f'/E_t{tt}'] = ee[:, :, :, ee.shape[3] // 2]
|
||||
|
||||
fdtd.accumulate_phasor(
|
||||
eph,
|
||||
omega,
|
||||
dt,
|
||||
ee,
|
||||
tt,
|
||||
# The pulse is delayed relative to t=0, so the extracted phasor
|
||||
# needs the same phase offset in its sample times.
|
||||
offset_steps=0.5 - delay / dt,
|
||||
# accumulate_phasor() already multiplies by dt, so pass the
|
||||
# discrete-sum normalization without its extra dt factor.
|
||||
weight=phasor_norm / dt,
|
||||
)
|
||||
fdtd.accumulate_phasor_j(jph, omega, dt, j_step, tt)
|
||||
fdtd.accumulate_phasor_e(eph, omega, dt, ee, tt + 1)
|
||||
fdtd.accumulate_phasor_h(hph, omega, dt, hh, tt + 1)
|
||||
|
||||
Eph = eph[0]
|
||||
Jph = jph[0]
|
||||
b = -1j * omega * Jph
|
||||
dxes_fdfd = copy.deepcopy(dxes)
|
||||
for pp in (-1, +1):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue