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 plot_monitors(sim, ax, output_plane=None, labels=False, monitor_parameters=None): if not sim._is_initialized: sim.init_sim() from meep.simulation import Volume # consolidate plotting parameters monitor_parameters = default_monitor_parameters if monitor_parameters is None else dict( default_monitor_parameters, **monitor_parameters) label = 'monitor' if labels else None for mon in sim.dft_objects: for reg in mon.regions: vol = Volume(center=reg.center, size=reg.size) ax = plot_volume(sim, ax, vol, output_plane, plotting_parameters=monitor_parameters, label=label) return ax
def plot_sources(sim, ax, output_plane=None, labels=False, source_parameters=None): if not sim._is_initialized: sim.init_sim() from meep.simulation import Volume # consolidate plotting parameters source_parameters = default_source_parameters if source_parameters is None else dict( default_source_parameters, **source_parameters) label = 'source' if labels else None for src in sim.sources: vol = Volume(center=src.center, size=src.size) ax = plot_volume(sim, ax, vol, output_plane, plotting_parameters=source_parameters, label=label) return ax
def plot2D(sim,ax=None, output_plane=None, fields=None, labels=False, eps_parameters=None,boundary_parameters=None, source_parameters=None,monitor_parameters=None, field_parameters=None, frequency=None, plot_eps_flag=True, plot_sources_flag=True, plot_monitors_flag=True, plot_boundaries_flag=True): # Initialize the simulation if sim.structure is None: sim.init_sim() # Ensure a figure axis exists if ax is None and mp.am_master(): from matplotlib import pyplot as plt ax = plt.gca() # Determine a frequency to plot all epsilon if frequency is None: try: # Continuous sources frequency = sim.sources[0].frequency except: try: # Gaussian sources frequency = sim.sources[0].src.frequency except: try: # Custom sources frequency = sim.sources[0].src.center_frequency except: # No sources frequency = 0 # validate the output plane to ensure proper 2D coordinates from meep.simulation import Volume sim_center, sim_size = get_2D_dimensions(sim,output_plane) output_plane = Volume(center=sim_center,size=sim_size) # Plot geometry if plot_eps_flag: ax = plot_eps(sim,ax,output_plane=output_plane,eps_parameters=eps_parameters,frequency=frequency) # Plot boundaries if plot_boundaries_flag: ax = plot_boundaries(sim,ax,output_plane=output_plane,boundary_parameters=boundary_parameters) # Plot sources if plot_sources_flag: ax = plot_sources(sim,ax,output_plane=output_plane,labels=labels,source_parameters=source_parameters) # Plot monitors if plot_monitors_flag: ax = plot_monitors(sim,ax,output_plane=output_plane,labels=labels,monitor_parameters=monitor_parameters) # Plot fields ax = plot_fields(sim,ax,fields,output_plane=output_plane,field_parameters=field_parameters) return ax
def get_boundary_volumes(thickness, direction, side): from meep.simulation import Volume thickness = boundary.thickness # Get domain measurements 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 cell_x = sim.cell_size.x cell_y = sim.cell_size.y cell_z = sim.cell_size.z if direction == mp.X and side == mp.Low: return Volume(center=Vector3(xmin + thickness / 2, sim.geometry_center.y, sim.geometry_center.z), size=Vector3(thickness, cell_y, cell_z)) elif direction == mp.X and side == mp.High: return Volume(center=Vector3(xmax - thickness / 2, sim.geometry_center.y, sim.geometry_center.z), size=Vector3(thickness, cell_y, cell_z)) elif direction == mp.Y and side == mp.Low: return Volume(center=Vector3(sim.geometry_center.x, ymin + thickness / 2, sim.geometry_center.z), size=Vector3(cell_x, thickness, cell_z)) elif direction == mp.Y and side == mp.High: return Volume(center=Vector3(sim.geometry_center.x, ymax - thickness / 2, sim.geometry_center.z), size=Vector3(cell_x, thickness, cell_z)) elif direction == mp.Z and side == mp.Low: return Volume(center=Vector3(sim.geometry_center.x, sim.geometry_center.y, zmin + thickness / 2), size=Vector3(cell_x, cell_y, thickness)) elif direction == mp.Z and side == mp.High: return Volume(center=Vector3(sim.geometry_center.x, sim.geometry_center.y, zmax - thickness / 2), size=Vector3(cell_x, cell_y, thickness)) else: raise ValueError("Invalid boundary type")
def get_boundary_volumes(thickness, direction, side, cylindrical=False): from meep.simulation import Volume thickness = boundary.thickness xmin, xmax, ymin, ymax, zmin, zmax = box_vertices( sim.geometry_center, sim.cell_size) if direction == mp.X and side == mp.Low: return Volume(center=Vector3(xmin + 0.5 * thickness, sim.geometry_center.y, sim.geometry_center.z), size=Vector3(thickness, sim.cell_size.y, sim.cell_size.z)) elif direction == mp.X and side == mp.High: return Volume(center=Vector3(xmax - 0.5 * thickness, sim.geometry_center.y, sim.geometry_center.z), size=Vector3(thickness, sim.cell_size.y, sim.cell_size.z)) elif direction == mp.Y and side == mp.Low: return Volume(center=Vector3(sim.geometry_center.x, ymin + 0.5 * thickness, sim.geometry_center.z), size=Vector3(sim.cell_size.x, thickness, sim.cell_size.z)) elif direction == mp.Y and side == mp.High: return Volume(center=Vector3(sim.geometry_center.x, ymax - 0.5 * thickness, sim.geometry_center.z), size=Vector3(sim.cell_size.x, thickness, sim.cell_size.z)) elif direction == mp.Z and side == mp.Low: return Volume(center=Vector3(sim.geometry_center.x, sim.geometry_center.y, zmin + 0.5 * thickness), size=Vector3(sim.cell_size.x, sim.cell_size.y, thickness)) elif direction == mp.Z and side == mp.High: return Volume(center=Vector3(sim.geometry_center.x, sim.geometry_center.y, zmax - 0.5 * thickness), size=Vector3(sim.cell_size.x, sim.cell_size.y, thickness)) else: raise ValueError("Invalid boundary type")
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
def plot2D(sim, ax=None, output_plane=None, fields=None, labels=False, eps_parameters=None, boundary_parameters=None, source_parameters=None, monitor_parameters=None, field_parameters=None, frequency=None, plot_eps_flag=True, plot_sources_flag=True, plot_monitors_flag=True, plot_boundaries_flag=True): # Ensure a figure axis exists if ax is None and mp.am_master(): from matplotlib import pyplot as plt ax = plt.gca() # validate the output plane to ensure proper 2D coordinates from meep.simulation import Volume sim_center, sim_size = get_2D_dimensions(sim, output_plane) output_plane = Volume(center=sim_center, size=sim_size) # Plot geometry if plot_eps_flag: ax = plot_eps(sim, ax, output_plane=output_plane, eps_parameters=eps_parameters, frequency=frequency) # Plot boundaries if plot_boundaries_flag: ax = plot_boundaries(sim, ax, output_plane=output_plane, boundary_parameters=boundary_parameters) # Plot sources if plot_sources_flag: ax = plot_sources(sim, ax, output_plane=output_plane, labels=labels, source_parameters=source_parameters) # Plot monitors if plot_monitors_flag: ax = plot_monitors(sim, ax, output_plane=output_plane, labels=labels, monitor_parameters=monitor_parameters) # Plot fields if fields is not None: ax = plot_fields(sim, ax, fields, output_plane=output_plane, field_parameters=field_parameters) return ax
def plot_volume(sim, ax, volume, output_plane=None, plotting_parameters=None, label=None): import matplotlib.patches as patches from matplotlib import pyplot as plt from meep.simulation import Volume # Set up the plotting parameters if plotting_parameters is None: plotting_parameters = default_volume_parameters else: plotting_parameters = dict(default_volume_parameters, **plotting_parameters) # Get domain measurements sim_center, sim_size = get_2D_dimensions(sim, output_plane) plane = Volume(center=sim_center, size=sim_size) size = volume.size center = volume.center xmin, xmax, ymin, ymax, zmin, zmax = box_vertices(center, size) # 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_volume(volume, plane) # Sort the points in a counter clockwise manner to ensure convex polygon is formed def sort_points(xy): xy = np.squeeze(xy) xy_mean = np.mean(xy, axis=0) theta = np.arctan2(xy[:, 1] - xy_mean[1], xy[:, 0] - xy_mean[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_size.y == 0: ax.scatter(center.x, center.z, **point_args) return ax elif sim_size.x == 0: ax.scatter(center.y, center.z, **point_args) return ax elif sim_size.z == 0: 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