-
Notifications
You must be signed in to change notification settings - Fork 640
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
get_eigenmode_coefficients() frequency dependence #1305
Comments
Indeed, the results from import meep as mp
import numpy as np
resolution = 20 # pixels/um
sxy = 16 # size of cell in X/Y directions
cell = mp.Vector3(sxy,sxy,0)
dpml = 1.0
pml_layers = [mp.PML(dpml)]
w = 1 # width of waveguide
geometry = [mp.Block(size=mp.Vector3(mp.inf,w,mp.inf),
center=mp.Vector3(),
material=mp.Medium(epsilon=12))]
fcen = 0.15 # pulse center frequency
df = 0.1 # pulse width (in frequency)
sources = [mp.EigenModeSource(src=mp.GaussianSource(fcen,fwidth=df),
eig_band=1,
eig_parity=mp.EVEN_Y+mp.ODD_Z,
center=mp.Vector3(-0.5*sxy+dpml,0,0),
size=mp.Vector3(0,sxy-2*dpml,0))]
symmetries = [mp.Mirror(direction=mp.Y)]
sim = mp.Simulation(cell_size=cell,
boundary_layers=pml_layers,
geometry=geometry,
sources=sources,
symmetries=symmetries,
resolution=resolution)
fr = mp.FluxRegion(center=mp.Vector3(0.5*sxy-dpml,0,0),
size=mp.Vector3(0,sxy-2*dpml,0))
freqs = np.array([0.15,0.15+0.3*df])
freqs = np.flipud(freqs)
tran = sim.add_flux(freqs,fr)
sim.run(until_after_sources=100)
coeffs = sim.get_eigenmode_coefficients(tran, [1], eig_parity=mp.EVEN_Y+mp.ODD_Z)
power = np.power(np.abs(coeffs.alpha[0,:,0]),2)
flux = mp.get_fluxes(tran)
for j in range(len(freqs)):
print("flux:, {} (freq), {} (flux), {} (mode coeffs.), {} (error)".format(freqs[j],flux[j],power[j],abs(flux[j]-power[j])/flux[j])) The output from two separate runs involving the same two values for the input 1. freqs = [ 0.15, 0.18 ]
2. freqs = [ 0.18, 0.15]
Note that the Poynting flux values (labeled |
I think this behavior may be related to #1233. One workaround is to simply reduce the |
Note that decreasing the tolerance as described tends to cause MPB to "oscillate" around a particular set of iterations, as described before the patch in #1233 was implemented. The kpoint finding routine needs more investigating. |
It's also important to note that the raw DFT fields pulled using |
I think we probably just need to ensure that the mode solver is completely deterministic — this way, any errors (e.g. from MPB's tolerance) will cancel when you do the finite-difference calculation. For now, that is as simple as calling |
It appears that any DFT monitor (in particular
get_eigenmode_coefficients()
) with some dependence on multiple field components does not reliably produce the same result for a given frequency array if said frequency array is shuffled. Here's an extreme example:The output is
Round 1 dft fields [(-0.008871683979082452+0.02179173297687087j), (-0.0010350658692419093+0.0010121248148330516j)] Round 1 eig coeffs: [[ 4.60069925+2.8010177j -0.13295154+1.97848851j]] FloatProgress(value=0.0, description='0% done ', max=277.5) Round 2 dft fields [(-0.001035065864159373+0.0010121248222745756j), (-0.008871683991283226+0.02179173293283784j)] Round 2 eig coeffs: [[-0.1329515 +1.97848851j 4.60069874+2.80101795j]] DFT difference: [ 1.22007734e-11+4.40330307e-11j -5.08253639e-12-7.44152396e-12j] eig coeffs difference: [[ 5.12833504e-07-2.55536971e-07j -4.34463213e-08+2.89126012e-09j]]
Note the large difference in eigenmode coefficients:1.39950082-2.47439812j, 0.59514822-0.85129899j
.Edit: I forgot to reseed the random generator for consistency between the two runs. Here's the actual error (still large):
5.12833504e-07-2.55536971e-07j -4.34463213e-08+2.89126012e-09j
@stevengj @oskooi
The text was updated successfully, but these errors were encountered: