def vis(): ### forces fig, ax = plt.subplots() force = np.zeros([3, len(separations)]) for i, separation in enumerate(separations): var = job.load(sim, f'p{i}') force[0, i] = var.Fx force[1, i] = var.Fy force[2, i] = var.Fz norm = job.load(norm_sim) ax.axhline(0, linestyle='--', color='black') ax.plot(separations / nm, force[0] / norm.norm * norm.area * constants.epsilon_0 / 2, 'o', color='C0', label='Fx (FDTD)') ax.plot(separations / nm, force[1] / norm.norm * norm.area * constants.epsilon_0 / 2, 'o', color='C1', label='Fy (FDTD)') ax.plot(separations / nm, force[2] / norm.norm * norm.area * constants.epsilon_0 / 2, 'o', color='C2', label='Fz (FDTD)') import miepy eps = meep_ext.get_eps(gold)(wavelength) Au = miepy.constant_material(eps * scale**2) water = miepy.constant_material(nb**2) source = miepy.sources.rhc_polarized_plane_wave() seps = np.linspace(300 * nm / scale, 900 * nm / scale, 100) force = np.zeros([3, len(seps)]) for i, sep in enumerate(seps): spheres = miepy.spheres([[-sep / 2, 0, 0], [sep / 2, 0, 0]], radius / scale, Au) sol = miepy.gmt(spheres, source, wavelength, 2, medium=water) F = sol.force_on_particle(1) force[:, i] = F.squeeze() ax.plot(seps * scale / nm, force[0], color='C0', label='Fx (GMT)') ax.plot(seps * scale / nm, force[1], color='C1', label='Fy (GMT)') ax.plot(seps * scale / nm, force[2], color='C2', label='Fz (GMT)') ax.set(xlabel='separation (nm)', ylabel='force') ax.legend() plt.show()
def vis(): ### cross-sections fig, ax = plt.subplots() scat = np.zeros([len(separations)]) absorb = np.zeros([len(separations)]) for i, separation in enumerate(separations): norm = job.load(norm_sim, f'p{i}') var = job.load(sim, f'p{i}') scat[i] = var.scattering / norm.norm * norm.area absorb[i] = var.absorption / norm.norm * norm.area ax.plot(separations / nm, scat, 'o', color='C0', label='scattering (FDTD)') ax.plot(separations / nm, absorb, 'o', color='C1', label='absorption (FDTD)') ax.plot(separations / nm, scat + absorb, 'o', color='C2', label='extinction (FDTD)') import miepy eps = meep_ext.get_eps(gold)(wavelength) Au = miepy.constant_material(eps) source = miepy.sources.rhc_polarized_plane_wave() seps = np.linspace(300 * nm, 900 * nm, 100) scat = np.zeros([len(seps)]) absorb = np.zeros([len(seps)]) extinct = np.zeros([len(seps)]) for i, sep in enumerate(seps): spheres = miepy.spheres([[-sep / 2, 0, 0], [sep / 2, 0, 0]], radius, Au) sol = miepy.gmt(spheres, source, wavelength, 2) scat[i], absorb[i], extinct[i] = sol.cross_sections() ax.plot(seps / nm, scat, color='C0', label='scattering (GMT)') ax.plot(seps / nm, absorb, color='C1', label='absorption (GMT)') ax.plot(seps / nm, extinct, color='C2', label='extinction (GMT)') ax.set(xlabel='separation (nm)', ylabel='cross-section') ax.legend() plt.show()
def vis(): ### forces fig, axes = plt.subplots(nrows=2, figsize=(7,6), sharex=True, gridspec_kw=dict(height_ratios=[2,1], hspace=0.05)) force = np.zeros([3,len(separations)]) for i,separation in enumerate(separations): var = job.load(sim, f'p{i}') force[0,i] = var.Fx force[1,i] = var.Fy force[2,i] = var.Fz norm = job.load(norm_sim) for ax in axes: ax.axhline(0, linestyle='--', color='black') ax.plot(separations/nm, force[0]/norm.norm*norm.area*constants.epsilon_0/2*1e25, 'o', color='C0', label='Fx (FDTD)') ax.plot(separations/nm, force[1]/norm.norm*norm.area*constants.epsilon_0/2*1e25, 'o', color='C1', label='Fy (FDTD)') ax.plot(separations/nm, force[2]/norm.norm*norm.area*constants.epsilon_0/2*1e25, 'o', color='C2', label='Fz (FDTD)') import miepy eps = meep_ext.get_eps(gold)(wavelength) Au = miepy.constant_material(eps) # Au = miepy.constant_material(3.5**2) source = miepy.sources.rhc_polarized_plane_wave() seps = np.linspace(300*nm, 900*nm, 100) force = np.zeros([3,len(seps)]) for i,sep in enumerate(seps): spheres = miepy.spheres([[-sep/2,0,0],[sep/2,0,0]], radius, Au) sol = miepy.gmt(spheres, source, wavelength, 2) F = sol.force_on_particle(1) force[:,i] = F.squeeze() for ax in axes: ax.plot(seps/nm, force[0]*1e25, color='C0', label='Fx (GMT)') ax.plot(seps/nm, force[1]*1e25, color='C1', label='Fy (GMT)') ax.plot(seps/nm, force[2]*1e25, color='C2', label='Fz (GMT)') axes[0].legend() axes[0].set(ylabel='force') axes[1].set(xlabel='separation (nm)', ylabel='force', ylim=[-3e-2, 3e-2]) plt.show()
nm = 1e-9 sep = 50*nm r = 20*nm fig,axes = plt.subplots(nrows=2, figsize=plt.figaspect(2)) Nx = 180 Ny = 181 x = np.linspace(-sep/2 - 2*r, sep/2 + 2*r, Nx) y = np.linspace(-2*r, 2*r, Ny) z = 0 X,Y,Z = np.meshgrid(x,y,z, indexing='ij') for i,sim in enumerate([True,False]): system = miepy.gmt(miepy.spheres([[-sep/2,0,0],[sep/2,0,0]], r, miepy.materials. Ag()), miepy.sources.plane_wave.from_string(polarization='x'), 600*nm, 2, interactions=sim) E = np.squeeze(system.E_field(X,Y,Z,True)) I = np.sum(np.abs(E)**2, axis=0) print(I.shape) mask = np.zeros((Nx,Ny), dtype=bool) mask[(np.squeeze(X)-sep/2)**2 + np.squeeze(Y)**2 < r**2] = True mask[(np.squeeze(X)+sep/2)**2 + np.squeeze(Y)**2 < r**2] = True I[mask] = 0 im = axes[i].pcolormesh(np.squeeze(X)/nm,np.squeeze(Y)/nm,I, shading='gouraud', rasterized=True) plt.colorbar(im, ax=axes[i], label='Intensity') axes[i].set(aspect='equal', xlabel='x (nm)', ylabel='y (nm)')
fig, axes = plt.subplots(ncols=2, figsize=plt.figaspect(1 / 2)) Nx = 50 Ny = 50 x = np.linspace(-5 * r, 5 * r, Nx) y = np.linspace(-5 * r, 5 * r, Ny) z = np.array([0]) X, Y, Z = np.meshgrid(x, y, z, indexing='xy') R = (X**2 + Y**2 + Z**2)**0.5 THETA = np.arccos(Z / R) PHI = np.arctan2(Y, X) system = miepy.gmt(miepy.spheres([0, 0, 0], r, miepy.constant_material(1.3)), miepy.sources.plane_wave.from_string(polarization='x'), 600 * nm, 2, interactions=False) E = np.squeeze(system.E_field(X, Y, Z, False)) I = np.sum(np.abs(E)**2, axis=0) print(E[:, 0, 0]) mask = np.zeros((Nx, Ny), dtype=bool) mask[(np.squeeze(Y))**2 + np.squeeze(X)**2 < 3.5 * r**2] = True I[mask] = 0 im = axes[0].pcolormesh(np.squeeze(X) / nm, np.squeeze(Y) / nm, I, shading='gouraud',
import miepy from math import factorial from tqdm import tqdm from scipy import constants nm = 1e-9 Ag = miepy.materials.Ag() # Ag = miepy.constant_material(4**2 + 0.01j) radius = 75 * nm source = miepy.sources.rhc_polarized_plane_wave(amplitude=2) separations = np.linspace(2 * radius + 10 * nm, 2 * radius + 700 * nm, 50) spheres = miepy.spheres( [[separations[0] / 2, 0, 0], [-separations[0] / 2, 0, 0]], radius, Ag) mie = miepy.gmt(spheres, source, 600 * nm, 2) analytic_force = np.zeros((3, ) + separations.shape) analytic_torque = np.zeros_like(analytic_force) mst_force = np.zeros_like(analytic_force) mst_torque = np.zeros_like(analytic_force) for i, separation in enumerate(tqdm(separations)): mie.update_position( np.array([[separation / 2, 0, 0], [-separation / 2, 0, 0]])) analytic_force[:, i] = mie.force_on_particle(0).squeeze() analytic_torque[:, i] = mie.torque_on_particle(0).squeeze() mst_force[:, i], mst_torque[:, i] = map( np.squeeze,
Nwav = 200 Ag = miepy.materials.Ag() radius = 75 * nm source = miepy.sources.x_polarized_plane_wave(amplitude=1) # separations = np.linspace(2*radius+10e-9,2*radius+700e-9, 50) separation = 153 * nm wavelengths = np.linspace(330 * nm, 1000 * nm, Nwav) separations = np.linspace(153 * nm, 300 * nm, 10) plt.figure(figsize=(5, 10)) for sep_idx, separation in enumerate(tqdm(separations)): spheres = miepy.spheres([[separation / 2, 0, 0], [-separation / 2, 0, 0]], radius, Ag) sol = miepy.gmt(spheres, source, wavelengths, 3, interactions=True) # sol.update_position(np.array([[separation/2,0,0], [-separation/2,0,0]])) r = 10000 * nm THETA, PHI = sphere_mesh(sampling) X, Y, Z = sph_to_cart(r, THETA, PHI) E = sol.E_field(X, Y, Z, inc=False) # H = sol.H_field(X,Y,Z, inc=False) I = np.sum(np.abs(E)**2, axis=0) dA = r**2 tau = np.linspace(-1, 1, sampling) phi = np.linspace(0, 2 * np.pi, 2 * sampling) flux = np.zeros_like(wavelengths)
def vis(): ### forces fig, ax = plt.subplots() norm = job.load(dimer_norm) scat = job.load(dimer_scat) ax.plot((1 / nm) / norm.frequency, scat.scattering / norm.incident * norm.area, 'o', color='C0', label='scattering (FDTD)') ax.plot((1 / nm) / norm.frequency, scat.absorption / norm.incident * norm.area, 'o', color='C1', label='absorption (FDTD)') ax.plot((1 / nm) / norm.frequency, (scat.scattering + scat.absorption) / norm.incident * norm.area, 'o', color='C2', label='extinction (FDTD)') import miepy wavelengths = np.linspace(400 * nm, 1000 * nm, 100) eps = meep_ext.get_eps(gold)(wavelengths) Au = miepy.data_material(wavelengths, eps) # Au = miepy.constant_material(3.5**2) spheres = miepy.spheres([[-sep / 2, 0, 0], [sep / 2, 0, 0]], radius, Au) source = miepy.sources.x_polarized_plane_wave() sol = miepy.gmt(spheres, source, wavelengths, 2) C, A, E = sol.cross_sections() ax.axhline(0, linestyle='--', color='black') ax.plot(wavelengths / nm, C, color='C0', label='scattering (GMT)') ax.plot(wavelengths / nm, A, color='C1', label='absorption (GMT)') ax.plot(wavelengths / nm, E, color='C2', label='extinction (GMT)') ax.legend() ax.set(xlabel='wavelength (nm)', ylabel='cross-section') ### field animation fig, ax = plt.subplots() x = np.linspace(0, cell[0] / nm, Nx) z = np.linspace(0, cell[1] / nm, Nz) X, Z = np.meshgrid(x, z, indexing='ij') var = job.load(dimer_fields) idx = np.s_[10:-10, 10:-10] E = var.E[:, 10:-10, 10:-10] # E = var.E vmax = np.max(np.abs(E)) / 2 im = ax.pcolormesh(X[idx], Z[idx], E[0], cmap='RdBu', animated=True, vmax=vmax, vmin=-vmax) ax.set_aspect('equal') def update(i): im.set_array(np.ravel(E[i][:-1, :-1])) return [im] ani = animation.FuncAnimation(fig, update, range(E.shape[0]), interval=50, blit=True) plt.show()
Ag = miepy.materials. Ag() radius = [100e-9, 75e-9] sources = {'x-polarized': miepy.sources.x_polarized_plane_wave(amplitude=1e6), 'y-polarized': miepy.sources.y_polarized_plane_wave(amplitude=1e6), 'rhc-polarized': miepy.sources.rhc_polarized_plane_wave(amplitude=1e6), } for name,source in sources.items(): plt.figure() separations = np.linspace(sum(radius)+10e-9,sum(radius)+700e-9, 70) force1 = [] force2 = [] spheres = miepy.spheres([[separations[0]/2,0,0], [-separations[0]/2,0,0]], radius, Ag) sol1 = miepy.gmt(spheres, source, 600e-9, 2, interactions=False) sol2 = miepy.gmt(spheres, source, 600e-9, 2, interactions=True) for separation in tqdm(separations): sol1.update_position(np.array([[separation/2,0,0], [-separation/2,0,0]])) F,T = map(np.squeeze, sol1.force()) force1.append(F[0,0] + F[0,1]) sol2.update_position(np.array([[separation/2,0,0], [-separation/2,0,0]])) F,T = map(np.squeeze, sol2.force()) force2.append(F[0,0] + F[0,1]) force1 = np.asarray(force1) force2 = np.asarray(force2) plt.plot((separations-sum(radius))*1e9, force1*1e12, label="no interactions") plt.plot((separations-sum(radius))*1e9, force2*1e12, label="interactions")
def vis(): ### forces fig, axes = plt.subplots(nrows=2, figsize=(7, 6), sharex=True, gridspec_kw=dict(height_ratios=[2, 1], hspace=0.05)) norm = job.load(dimer_norm) scat = job.load(dimer_scat) for ax in axes: ax.plot((1 / nm) / norm.frequency, scat.Fx / norm.incident * norm.area * constants.epsilon_0 / 2 * 1e25, 'o', color='C0', label='Fx (FDTD)') ax.plot((1 / nm) / norm.frequency, scat.Fy / norm.incident * norm.area * constants.epsilon_0 / 2 * 1e25, 'o', color='C1', label='Fy (FDTD)') ax.plot((1 / nm) / norm.frequency, scat.Fz / norm.incident * norm.area * constants.epsilon_0 / 2 * 1e25, 'o', color='C2', label='Fz (FDTD)') import miepy wavelengths = np.linspace(400 * nm, 1000 * nm, 100) eps = meep_ext.get_eps(gold)(wavelengths) Au = miepy.data_material(wavelengths, eps) # Au = miepy.constant_material(3.5**2) spheres = miepy.spheres([[-sep / 2, 0, 0], [sep / 2, 0, 0]], radius, Au) source = miepy.sources.rhc_polarized_plane_wave() sol = miepy.gmt(spheres, source, wavelengths, 2) F = sol.force_on_particle(1) for ax in axes: ax.axhline(0, linestyle='--', color='black') ax.plot(wavelengths / nm, F[0] * 1e25, color='C0', label='Fx (GMT)') ax.plot(wavelengths / nm, F[1] * 1e25, color='C1', label='Fy (GMT)') ax.plot(wavelengths / nm, F[2] * 1e25, color='C2', label='Fz (GMT)') axes[0].legend() axes[0].set(ylabel='force') axes[1].set(xlabel='wavelength (nm)', ylabel='force', ylim=[-0.035, 0.01]) ### field animation fig, ax = plt.subplots() x = np.linspace(0, cell[0] / nm, Nx) z = np.linspace(0, cell[1] / nm, Nz) X, Z = np.meshgrid(x, z, indexing='ij') var = job.load(dimer_fields) idx = np.s_[10:-10, 10:-10] E = var.E[:, 10:-10, 10:-10] # E = var.E vmax = np.max(np.abs(E)) / 2 im = ax.pcolormesh(X[idx], Z[idx], E[0], cmap='RdBu', animated=True, vmax=vmax, vmin=-vmax) ax.set_aspect('equal') def update(i): im.set_array(np.ravel(E[i][:-1, :-1])) return [im] ani = animation.FuncAnimation(fig, update, range(E.shape[0]), interval=50, blit=True) plt.show()
Nwav = 60 Au = miepy.materials.Au() radius = 40 * nm source = miepy.sources.x_polarized_plane_wave(amplitude=1) # separations = np.linspace(2*radius+10e-9,2*radius+700e-9, 50) wavelengths = np.linspace(300 * nm, 800 * nm, Nwav) separation = 83 * nm flux = np.zeros_like(wavelengths) flux2 = np.zeros_like(wavelengths) plt.figure() for wav_idx, wav in enumerate(tqdm(wavelengths)): spheres = miepy.spheres([[separation / 2, 0, 0], [-separation / 2, 0, 0]], radius, Au) sol = miepy.gmt(spheres, source, wav, 2, interactions=True) scat = sol.scattering_cross_section() flux2[wav_idx] = np.sum(scat) # sol.update_position(np.array([[separation/2,0,0], [-separation/2,0,0]])) r = 10000 * nm THETA, PHI = sphere_mesh(sampling) X, Y, Z = sph_to_cart(r, THETA, PHI) E = sol.E_field(X, Y, Z, inc=False) # H = sol.H_field(X,Y,Z, inc=False) I = np.sum(np.abs(E)**2, axis=0).squeeze() dA = r**2