-
Notifications
You must be signed in to change notification settings - Fork 646
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
oblique-waveguide support in mode decomposition #693
Comments
In particular, @fesc3555 already worked out that the Poynting flux is invariant under coordinate transformations (https://github.com/fesc3555/meep_variable_resolution/blob/master/notes.pdf). It would be worthwhile going through a similar procedure to see if the mode inner product ∫(E₁×H₂ + E₂×H₁)⋅dA has the same feature. |
Looking through Felix's notes, I think it works out — he shows that ∫E×H⋅dA is invariant under coordinate transformations, but does not require that E and H belong to the same mode (i.e. one doesn't have to be the curl of the other), only that they transform in the same way. This should mean that the modal inner product is invariant as well. As a result, I think we can use the existing mode-decomposition feature as-is as long as we plug the oblique-waveguide modes into it. |
In particular, it mainly looks like we need a way to pass For now, you could just hack this line to pass |
With the suggested one-line hack in import meep as mp
import numpy as np
resolution = 50 # pixels/μm
cell_size = mp.Vector3(14,14)
pml_layers = [mp.PML(thickness=2)]
# rotation angle (in degrees) of waveguide, counter clockwise (CCW) around z-axis
rot_angle = np.radians(40)
geometry = [mp.Block(center=mp.Vector3(),
size=mp.Vector3(mp.inf,1,mp.inf),
e1=mp.Vector3(1).rotate(mp.Vector3(z=1), rot_angle),
e2=mp.Vector3(y=1).rotate(mp.Vector3(z=1), rot_angle),
material=mp.Medium(epsilon=12))]
fsrc = 0.15 # frequency of eigenmode or constant-amplitude source
kx = 0.4 # initial guess for wavevector in x-direction of eigenmode
bnum = 1 # band number of eigenmode
sources = [mp.EigenModeSource(src=mp.GaussianSource(fsrc,fwidth=0.2*fsrc),
center=mp.Vector3(),
size=mp.Vector3(y=14),
direction=mp.AUTOMATIC if rot_angle == 0 else mp.NO_DIRECTION,
eig_kpoint=mp.Vector3(kx).rotate(mp.Vector3(z=1), rot_angle),
eig_band=bnum,
eig_parity=mp.EVEN_Y+mp.ODD_Z if rot_angle == 0 else mp.ODD_Z,
eig_match_freq=True)]
sim = mp.Simulation(cell_size=cell_size,
resolution=resolution,
boundary_layers=pml_layers,
sources=sources,
geometry=geometry,
symmetries=[mp.Mirror(mp.Y)] if rot_angle == 0 else [])
tran = sim.add_flux(fsrc, 0, 1, mp.FluxRegion(center=mp.Vector3(x=5), size=mp.Vector3(y=14)))
sim.run(until_after_sources=50)
res = sim.get_eigenmode_coefficients(tran,
[1],
eig_parity=mp.EVEN_Y+mp.ODD_Z if rot_angle == 0 else mp.ODD_Z,
kpoint_func=lambda f,n: mp.Vector3(kx).rotate(mp.Vector3(z=1), rot_angle))
mode_coeffs = res.alpha
print("flux:, {:.6f}, {:.6f}".format(mp.get_fluxes(tran)[0], abs(mode_coeffs[0,0,0])**2)) rotation angle: 10°
rotation angle: 20°
rotation angle: 30°
rotation angle: 40°
These values are all within less than 2% of one another. For comparison, the following are the results from master.
rotation angle: 20°
rotation angle: 30°
rotation angle: 40°
The difference in the pairs of values increases with the rotation angle (it is ~26% for a rotation angle of 40°). Since |
Once #675 is merged, it would be good to support the same feature in the mode-decomposition code.
Hopefully it will be straightforward, but may need a little thought about how mode-orthogonality works in this kind of oblique setting, since that's not the usual setting where this property is derived.
The text was updated successfully, but these errors were encountered: