Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
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
Ejemplo n.º 4
0
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
Ejemplo n.º 5
0
    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")
Ejemplo n.º 6
0
    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")
Ejemplo n.º 7
0
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
Ejemplo n.º 8
0
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
Ejemplo n.º 9
0
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