Beispiel #1
0
def cubic_param_shape(
    initializer: Callable,
    extents: np.ndarray,
    pixel_spacing: float,
    control_point_spacing: float,
    pos: Union[np.ndarray, goos.Function],
    var_name: Optional[str] = None,
    reflection_symmetry: List[int] = None,
    periods: List[int] = None,
    **kwargs,
) -> Tuple[goos.Variable, Shape]:
    """Creates a new continuous parametrization using bicubic interpolation.

    The values of the parametrization are governed by bicubic interpolation
    on certain control points. Control points are defined with spacing
    given by `control_point_spacing`.

    Args:
        initializer: A callable to initialize values for the shape. This should
            accept a single argument `size` and return an array of values with
            shape `size`.
        extents: Extents of the shape.
        pixel_spacing: The pixel size will be given by
            `(pixel_spacing, pixel_spacing, extents[2])`.
        control_point_spacing: Spacing between two control points.
        var_name: Name to give the variable.
        pos: Position of the shape.
        **kwargs: Additional argument to pass to shape constructor.

    Returns:
        A tuple `(var, shape)` where `var` is the variable containing the values
        and `shape` is the newly created shape.
    """
    # TODO(vcruysse): Stop using the old parametrization implementation.
    from spins.goos import compat
    from spins.invdes.problem_graph import optplan

    if not isinstance(pos, goos.Function):
        pos = goos.Constant(pos)

    return compat.compat_param(
        param=optplan.CubicParametrization(
            undersample=control_point_spacing / pixel_spacing,
            reflection_symmetry=reflection_symmetry,
            periods=periods),
        initializer=initializer,
        extents=extents,
        pixel_size=[pixel_spacing, pixel_spacing, extents[2]],
        pos=pos,
        var_name=var_name,
        **kwargs)
Beispiel #2
0
def create_transformations(
    obj: optplan.Function,
    monitors: List[optplan.Monitor],
    sim_space: optplan.SimulationSpaceBase,
    cont_iters: int,  # require more to optimise power better
    num_stages: int = 3,
    min_feature: float = 100,
) -> List[optplan.Transformation]:
    """Creates a list of transformations for the device optimization.

    The transformations dictate the sequence of steps used to optimize the
    device. The optimization uses `num_stages` of continuous optimization. For
    each stage, the "discreteness" of the structure is increased (through
    controlling a parameter of a sigmoid function).

    Args:
        opt: The objective function to minimize.
        monitors: List of monitors to keep track of.
        sim_space: Simulation space ot use.
        cont_iters: Number of iterations to run in continuous optimization
            total across all stages.
        num_stages: Number of continuous stages to run. The more stages that
            are run, the more discrete the structure will become.
        min_feature: Minimum feature size in nanometers.

    Returns:
        A list of transformations.
    """
    # Setup empty transformation list.
    trans_list = []

    # First do continuous relaxation optimization.
    # This is done through cubic interpolation and then applying a sigmoid
    # function.
    param = optplan.CubicParametrization(
        # Specify the coarseness of the cubic interpolation points in terms
        # of number of Yee cells. Feature size is approximated by having
        # control points on the order of `min_feature / GRID_SPACING`.
        undersample=3.5 * min_feature / GRID_SPACING,
        simulation_space=sim_space,
        init_method=optplan.UniformInitializer(min_val=0.6, max_val=0.9),
    )

    iters = max(cont_iters // num_stages, 1)
    for stage in range(num_stages):
        trans_list.append(
            optplan.Transformation(
                name="opt_cont{}".format(stage),
                parametrization=param,
                transformation=optplan.ScipyOptimizerTransformation(
                    optimizer="L-BFGS-B",
                    objective=obj,
                    monitor_lists=optplan.ScipyOptimizerMonitorList(
                        callback_monitors=monitors,
                        start_monitors=monitors,
                        end_monitors=monitors),
                    optimization_options=optplan.ScipyOptimizerOptions(
                        maxiter=iters),
                ),
            ))

        if stage < num_stages - 1:
            # Make the structure more discrete.
            trans_list.append(
                optplan.Transformation(
                    name="sigmoid_change{}".format(stage),
                    parametrization=param,
                    # The larger the sigmoid strength value, the more "discrete"
                    # structure will be.
                    transformation=optplan.CubicParamSigmoidStrength(
                        value=4 * (stage + 1)),
                ))
    return trans_list
Beispiel #3
0
def create_transformations(
    obj: optplan.Function,
    monitors: List[optplan.Monitor],
    sim_space: optplan.SimulationSpaceBase,
    cont_iters: int,
    num_stages: int = 3,
    min_feature: float = 100,
) -> List[optplan.Transformation]:
    """Creates a list of transformations for the device optimization.

    The transformations dictate the sequence of steps used to optimize the
    device. The optimization uses `num_stages` of continuous optimization. For
    each stage, the "discreteness" of the structure is increased (through
    controlling a parameter of a sigmoid function).

    Args:
        obj: The objective function to minimize.
        monitors: List of monitors to keep track of.
        sim_space: Simulation space ot use.
        cont_iters: Number of iterations to run in continuous optimization
            total across all stages.
        num_stages: Number of continuous stages to run. The more stages that
            are run, the more discrete the structure will become.
        min_feature: Minimum feature size in nanometers.
        fab_obj: Objective including fabrication penalties to be used in the
            second half of the optimization

    Returns:
        A list of transformations.
    """
    # Setup empty transformation list.
    trans_list = []

    # First do continuous relaxation optimization.
    # This is done through cubic interpolation and then applying a sigmoid
    # function.
    param = optplan.CubicParametrization(
        # Specify the coarseness of the cubic interpolation points in terms
        # of number of Yee cells. Feature size is approximated by having
        # control points on the order of `min_feature / GRID_SPACING`.
        undersample=3.5 * min_feature / GRID_SPACING,
        simulation_space=sim_space,
        init_method=optplan.WaveguideInitializer3(lower_min=0,
                                                  lower_max=.2,
                                                  upper_min=.7,
                                                  upper_max=1,
                                                  extent_frac_x=1,
                                                  extent_frac_y=1 / 2,
                                                  center_frac_x=1 / 2,
                                                  center_frac_y=1 / 2),
        # init_method=optplan.GradientInitializer(min=0, max=1, random=0.3, extent_frac_x=1, extent_frac_y=0.4,
        #                                         center_frac_x=0.5, center_frac_y=0.55)
        # init_method=optplan.UniformInitializer(min_val=0, max_val=0)
        # init_method=optplan.PeriodicInitializer(random=0.2, min=0, max=1, period=400, sim_width=6000,
        #                                         center_frac_y=0.5, extent_frac_y=0.4)
    )

    trans_list.append(
        optplan.Transformation(
            name="sigmoid_change_init",
            parametrization=param,
            # The larger the sigmoid strength value, the more "discrete"
            # structure will be.
            transformation=optplan.CubicParamSigmoidStrength(value=4, )))

    iters = max(cont_iters // num_stages, 1)
    for stage in range(num_stages):
        trans_list.append(
            optplan.Transformation(
                name="opt_cont{}".format(stage),
                parametrization=param,
                transformation=optplan.ScipyOptimizerTransformation(
                    optimizer="L-BFGS-B",
                    objective=obj,
                    monitor_lists=optplan.ScipyOptimizerMonitorList(
                        callback_monitors=monitors,
                        start_monitors=monitors,
                        end_monitors=monitors),
                    optimization_options=optplan.ScipyOptimizerOptions(
                        maxiter=iters),
                ),
            ))

        if stage < num_stages - 1:
            # Make the structure more discrete.
            trans_list.append(
                optplan.Transformation(
                    name="sigmoid_change{}".format(stage),
                    parametrization=param,
                    # The larger the sigmoid strength value, the more "discrete"
                    # structure will be.
                    transformation=optplan.CubicParamSigmoidStrength(
                        value=2 * (stage + 3)),
                ))
    return trans_list