class ShapeFlow(flows.Flow): pos: np.ndarray = flows.np_zero_field(3) rot: np.ndarray = flows.np_zero_field(3) priority: int = flows.constant_field(default=0) material: str = flows.constant_field(default=None)
class NewFlow(flows.Flow): pos: np.ndarray = flows.np_zero_field(3) priority: int = flows.constant_field(default=0)
class PixelatedContShapeFlow(ShapeFlow, goos.NumericFlow): """Represents a shape with continuous permittivity distribution. A pixelated continuous shape flow splits up a rectangular block into pixels with size given by `pixel_size`. Each pixel has a given value as given by `array`. The centers of the pixels relative to the center of the shape can be computed by calling `get_relative_cell_coords`. Attributes: material2: The "upper" material. This material permittivity is used when the value is equal to 1 (`material` defined in `ShapeFlow` is used when the value is equal to 0). array: List of values corresponding to the normalized permittivity, usually between 0 and 1. extents: Extents of space that the shape occupies. The extruded direction is along z-axis. pixel_size: List of 3 values indicating size of the pixels along x, y, and z axes. """ material2: str = flows.constant_field(default=None) extents: np.ndarray = flows.np_zero_field(3) pixel_size: np.ndarray = flows.constant_field( default_factory=lambda: np.zeros(3)) @classmethod def get_relative_cell_coords(cls, extents: np.ndarray, pixel_size: np.ndarray) -> List[np.ndarray]: """Returns coordinates of the cell relative to the shape center. Args: extents: Extents of the shape. pixel_size: Size of each pixel. Returns: List `(x_coords, y_coords, z_coords)` where `x_coords` is a list of the x-coordinate centers and so forth. """ edge_coords = cls.get_relative_edge_coords(extents, pixel_size) return [(coord[:-1] + coord[1:]) / 2 for coord in edge_coords] coords = [] for i in range(len(extents)): coord = pixel_size[i] * np.arange( 0, int(extents[i] / pixel_size[i]) + 1) if coord[-1] >= extents[i]: coords.append(coord[:-1]) else: coords.append(coord) return [coord - np.mean(coord) for coord in coords] def get_cell_coords(self) -> List[np.ndarray]: """Returns the absolute coordinates of the cells.""" rel_cell_coords = PixelatedContShapeFlow.get_relative_cell_coords( self.extents, self.pixel_size) return [coords + p for coords, p in zip(rel_cell_coords, self.pos)] @classmethod def get_relative_edge_coords(cls, extents: np.ndarray, pixel_size: np.ndarray) -> List[np.ndarray]: """Returns coordinates of the cell edges relative to the shape center. Args: extents: Extents of the shape. pixel_size: Size of each pixel. Returns: List `(x_coords, y_coords, z_coords)` where `x_coords` is a list of the x-coordinate edges and so forth. """ # Compute edge coordinates assuming that each pixel is `pixel_size` # large. edge_coords = [] for i in range(len(extents)): num_pixels = np.ceil(extents[i] / pixel_size[i]) if num_pixels * pixel_size[i] < extents[i]: num_pixels += 1 coord = pixel_size[i] * np.arange(0, num_pixels + 1) edge_coords.append(coord - (coord[0] + coord[-1]) / 2) # The edges could have smaller pixel sizes because they are cut off. # Account for this difference. for i in range(len(extents)): edge_coords[i][0] = -extents[i] / 2 edge_coords[i][-1] = extents[i] / 2 return edge_coords def get_edge_coords(self) -> List[np.ndarray]: """Returns the absolute coordinates of the cell edges.""" rel_edge_coords = PixelatedContShapeFlow.get_relative_edge_coords( self.extents, self.pixel_size) return [coords + p for coords, p in zip(rel_edge_coords, self.pos)] @classmethod def get_shape(cls, extents: np.ndarray, pixel_size: np.ndarray) -> List[int]: """Returns shape of the values array. Args: extents: Extents of the shape. pixel_size: Size of each pixel. Returns: List of the shape of the values array. """ shape = [] for i in range(3): size = int(extents[i] / pixel_size[i]) + 1 if pixel_size[i] * (size - 1) >= extents[i]: size -= 1 shape.append(size) return shape
class NewFlow(flows.Flow): pos: int = 0 rot: float = 0 priority: int = flows.constant_field(default=0)