def test_get_center_and_size(self): v1d = mp.volume(mp.vec(-2), mp.vec(2)) center, size = mp.get_center_and_size(v1d) self.assertTrue(center.close(mp.Vector3())) self.assertTrue(size.close(mp.Vector3(z=4))) v2d = mp.volume(mp.vec(-1, -1), mp.vec(1, 1)) center, size = mp.get_center_and_size(v2d) self.assertTrue(center.close(mp.Vector3())) self.assertTrue(size.close(mp.Vector3(2, 2))) v3d = mp.volume(mp.vec(-1, -1, -1), mp.vec(1, 1, 1)) center, size = mp.get_center_and_size(v3d) self.assertTrue(center.close(mp.Vector3())) self.assertTrue(size.close(mp.Vector3(2, 2, 2)))
def get_2D_dimensions(sim, output_plane): from meep.simulation import Volume # Pull correct plane from user if output_plane: plane_center, plane_size = (output_plane.center, output_plane.size) elif sim.output_volume: plane_center, plane_size = mp.get_center_and_size(sim.output_volume) else: plane_center, plane_size = (sim.geometry_center, sim.cell_size) plane_volume = Volume(center=plane_center, size=plane_size) if plane_size.x != 0 and plane_size.y != 0 and plane_size.z != 0: raise ValueError("Plane volume must be 2D (a plane).") check_volume = Volume(center=sim.geometry_center, size=sim.cell_size) vertices = intersect_volume_volume(check_volume, plane_volume) if len(vertices) == 0: raise ValueError( "The specified user volume is completely outside of the simulation domain." ) intersection_vol = Volume(vertices=vertices) if (intersection_vol.size != plane_volume.size) or ( intersection_vol.center != plane_volume.center): warnings.warn( 'The specified user volume is larger than the simulation domain and has been truncated.' ) sim_center, sim_size = (intersection_vol.center, intersection_vol.size) return sim_center, sim_size
def visualize_dft_flux(sim, superpose=True, flux_cells=[], options=None, nf=0): if not mp.am_master(): return options=options if options else def_flux_options # first pass to get arrays of poynting flux strength for all cells if len(flux_cells)==0: flux_cells=[cell for cell in sim.dft_objects if is_flux_cell(cell)] flux_arrays=[] for cell in flux_cells: # first pass to compute flux data (x,y,z,w,c,EH)=unpack_dft_cell(sim,cell,nf=nf) flux_arrays.append( 0.25*np.real(w*(np.conj(EH[0])*EH[3] - np.conj(EH[1])*EH[2])) ) # second pass to plot for n, cell in enumerate(flux_cells): # second pass to plot if superpose==False: if n==0: plt.figure() plt.title('Poynting flux') plt.subplot(len(flux_cells),1,n) plt.gca().set_title('Flux cell {}'.format(n)) cn,sz=mp.get_center_and_size(cell.where) max_flux=np.amax([np.amax(fa) for fa in flux_arrays]) plot_data_curves(sim, center=cn, size=sz, data=[flux_arrays[n]], superpose=superpose, options=options, labels=['flux through cell {}'.format(n)], dmin=-max_flux,dmax=max_flux)
def visualize_dft_flux(sim, superpose=True, flux_cells=[], options=None, nf=0): if not mp.am_master(): return options = options if options else def_flux_options # first pass to get arrays of poynting flux strength for all cells if len(flux_cells) == 0: flux_cells = [cell for cell in sim.dft_objects if is_flux_cell(cell)] flux_arrays = [] for cell in flux_cells: # first pass to compute flux data (x, y, z, w, c, EH) = unpack_dft_cell(sim, cell, nf=nf) flux_arrays.append( 0.25 * np.real(w * (np.conj(EH[0]) * EH[3] - np.conj(EH[1]) * EH[2]))) # second pass to plot for n, cell in enumerate(flux_cells): # second pass to plot if superpose == False: if n == 0: plt.figure() plt.title('Poynting flux') plt.subplot(len(flux_cells), 1, n) plt.gca().set_title('Flux cell {}'.format(n)) cn, sz = mp.get_center_and_size(cell.where) max_flux = np.amax([np.amax(fa) for fa in flux_arrays]) plot_data_curves(sim, center=cn, size=sz, data=[flux_arrays[n]], superpose=superpose, options=options, labels=['flux through cell {}'.format(n)], dmin=-max_flux, dmax=max_flux)
def plot_eps(sim, ax, output_plane=None, eps_parameters=None): if sim.structure is None: sim.init_sim() # consolidate plotting parameters eps_parameters = default_eps_parameters if eps_parameters is None else dict( default_eps_parameters, **eps_parameters) # Get domain measurements if output_plane: sim_center, sim_size = (output_plane.center, output_plane.size) elif sim.output_volume: sim_center, sim_size = mp.get_center_and_size(sim.output_volume) else: sim_center, sim_size = (sim.geometry_center, sim.cell_size) xmin = sim_center.x - sim_size.x / 2 xmax = sim_center.x + sim_size.x / 2 ymin = sim_center.y - sim_size.y / 2 ymax = sim_center.y + sim_size.y / 2 zmin = sim_center.z - sim_size.z / 2 zmax = sim_center.z + sim_size.z / 2 center = Vector3(sim_center.x, sim_center.y, sim_center.z) cell_size = Vector3(sim_size.x, sim_size.y, sim_size.z) if sim_size.x == 0: # Plot y on x axis, z on y axis (YZ plane) extent = [ymin, ymax, zmin, zmax] xlabel = 'Y' ylabel = 'Z' elif sim_size.y == 0: # Plot x on x axis, z on y axis (XZ plane) extent = [xmin, xmax, zmin, zmax] xlabel = 'X' ylabel = 'Z' elif sim_size.z == 0: # Plot x on x axis, y on y axis (XY plane) extent = [xmin, xmax, ymin, ymax] xlabel = 'X' ylabel = 'Y' else: raise ValueError("A 2D plane has not been specified...") eps_data = np.rot90( np.real( sim.get_array(center=center, size=cell_size, component=mp.Dielectric))) if mp.am_master(): ax.imshow(eps_data, extent=extent, **eps_parameters) ax.set_xlabel(xlabel) ax.set_ylabel(ylabel) return ax
def plot_fields(sim, ax=None, fields=None, output_plane=None, field_parameters=None): if not sim._is_initialized: sim.init_sim() if fields is None: return ax # user specifies a field component if fields in [mp.Ex, mp.Ey, mp.Ez, mp.Hx, mp.Hy, mp.Hz]: # Get domain measurements if output_plane: sim_center, sim_size = (output_plane.center, output_plane.size) elif sim.output_volume: sim_center, sim_size = mp.get_center_and_size(sim.output_volume) else: sim_center, sim_size = (sim.geometry_center, sim.cell_size) xmin = sim_center.x - sim_size.x / 2 xmax = sim_center.x + sim_size.x / 2 ymin = sim_center.y - sim_size.y / 2 ymax = sim_center.y + sim_size.y / 2 zmin = sim_center.z - sim_size.z / 2 zmax = sim_center.z + sim_size.z / 2 center = Vector3(sim_center.x, sim_center.y, sim_center.z) cell_size = Vector3(sim_size.x, sim_size.y, sim_size.z) if sim_size.x == 0: # Plot y on x axis, z on y axis (YZ plane) extent = [ymin, ymax, zmin, zmax] xlabel = 'Y' ylabel = 'Z' elif sim_size.y == 0: # Plot x on x axis, z on y axis (XZ plane) extent = [xmin, xmax, zmin, zmax] xlabel = 'X' ylabel = 'Z' elif sim_size.z == 0: # Plot x on x axis, y on y axis (XY plane) extent = [xmin, xmax, ymin, ymax] xlabel = 'X' ylabel = 'Y' fields = sim.get_array(center=center, size=cell_size, component=fields) else: raise ValueError( 'Please specify a valid field component (mp.Ex, mp.Ey, ...') # Either plot the field, or return the array if ax: field_parameters = default_field_parameters if field_parameters is None else dict( default_field_parameters, **field_parameters) if mp.am_master(): ax.imshow(np.rot90(fields), extent=extent, **field_parameters) return ax else: return np.rot90(fields) return ax
def plot_volume(sim, ax, volume, output_plane=None, plotting_parameters=None, label=None): if not sim._is_initialized: sim.init_sim() import matplotlib.patches as patches from matplotlib import pyplot as plt from meep.simulation import Volume # Set up the plotting parameters plotting_parameters = default_volume_parameters if plotting_parameters is None else dict( default_volume_parameters, **plotting_parameters) # Get domain measurements if output_plane: sim_center, sim_size = (output_plane.center, output_plane.size) elif sim.output_volume: sim_center, sim_size = mp.get_center_and_size(sim.output_volume) else: sim_center, sim_size = (sim.geometry_center, sim.cell_size) plane = Volume(center=sim_center, size=sim_size) # Pull volume parameters size = volume.size center = volume.center xmax = center.x + size.x / 2 xmin = center.x - size.x / 2 ymax = center.y + size.y / 2 ymin = center.y - size.y / 2 zmax = center.z + size.z / 2 zmin = center.z - size.z / 2 # Add labels if requested if label is not None and mp.am_master(): if sim_size.x == 0: ax = place_label(ax, label, center.y, center.z, sim_center.y, sim_center.z, label_parameters=plotting_parameters) elif sim_size.y == 0: ax = place_label(ax, label, center.x, center.z, sim_center.x, sim_center.z, label_parameters=plotting_parameters) elif sim_size.z == 0: ax = place_label(ax, label, center.x, center.y, sim_center.x, sim_center.y, label_parameters=plotting_parameters) # Intersect plane with volume intersection = intersect_volume_plane(volume, plane) # Sort the points in a counter clockwise manner to ensure convex polygon is formed def sort_points(xy): xy = np.squeeze(xy) theta = np.arctan2(xy[:, 1], xy[:, 0]) return xy[np.argsort(theta, axis=0)] if mp.am_master(): # Point volume if len(intersection) == 1: point_args = { key: value for key, value in plotting_parameters.items() if key in ['color', 'marker', 'alpha', 'linewidth'] } if sim_center.y == center.y: ax.scatter(center.x, center.z, **point_args) return ax elif sim_center.x == center.x: ax.scatter(center.y, center.z, **point_args) return ax elif sim_center.z == center.z: ax.scatter(center.x, center.y, **point_args) return ax else: return ax # Line volume elif len(intersection) == 2: line_args = { key: value for key, value in plotting_parameters.items() if key in ['color', 'linestyle', 'linewidth', 'alpha'] } # Plot YZ if sim_size.x == 0: ax.plot([a.y for a in intersection], [a.z for a in intersection], **line_args) return ax #Plot XZ elif sim_size.y == 0: ax.plot([a.x for a in intersection], [a.z for a in intersection], **line_args) return ax # Plot XY elif sim_size.z == 0: ax.plot([a.x for a in intersection], [a.y for a in intersection], **line_args) return ax else: return ax # Planar volume elif len(intersection) > 2: planar_args = { key: value for key, value in plotting_parameters.items() if key in ['edgecolor', 'linewidth', 'facecolor', 'hatch', 'alpha'] } # Plot YZ if sim_size.x == 0: ax.add_patch( patches.Polygon( sort_points([[a.y, a.z] for a in intersection]), **planar_args)) return ax #Plot XZ elif sim_size.y == 0: ax.add_patch( patches.Polygon( sort_points([[a.x, a.z] for a in intersection]), **planar_args)) return ax # Plot XY elif sim_size.z == 0: ax.add_patch( patches.Polygon( sort_points([[a.x, a.y] for a in intersection]), **planar_args)) return ax else: return ax else: return ax return ax