Skip to content

Commit

Permalink
Version 0.2.8
Browse files Browse the repository at this point in the history
* Fix a bug for mesh region error in FDTDSimulation.
* Add draw function for CirclePixelsRegion&RectanglePixelsRegion.
* *load_file* param for FDTDSimulation & MODESimulation.
  • Loading branch information
Hideousmon committed Dec 21, 2021
1 parent b490058 commit 9205b5c
Show file tree
Hide file tree
Showing 7 changed files with 133 additions and 17 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -120,4 +120,7 @@ docs/Makefile
docs/make.bat
docs/_build
temporal_tests
asnn_tests
asnn_tests
layout_tests
sim_tests
*.rar
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,3 +169,8 @@ A polarization beam splitter inverse design example can be found [here](https://

### Version 0.2.7 (Dec 16, 2021)
* New Classes for Inverse Design with Adjoint Method: ShapeOptRegion2D, ShapeOptRegion3D, TopologyOptRegion2D, TopologyOptRegion3D, AdjointForShapeOpt, AdjointForTO.

### Version 0.2.8 (DEC 21, 2021)
* Fix a bug for mesh region error in FDTDSimulation.
* Add draw functions for CirclePixelsRegion&RectanglePixelsRegion.
* *load_file* param for FDTDSimulation & MODESimulation.
12 changes: 9 additions & 3 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ SPLayout

|GitHub repository| |GitHub license|

SPLayout (**S**\ilicon **P**\hotonics **Layout** Design Tools) is a package for silicon photonics structures design. It provides commonly used silicon photonics structure classes for fast integration and pixelized blocks for inverse design and optimization. Some inverse design algorithms are also integrated in it like DBS(Direct Binary Search) and BBA(Bat Binary Algorithms).
SPLayout (**S**\ilicon **P**\hotonics **Layout** Design Tools) is a package for silicon photonics structures design. It provides commonly used silicon photonics structure classes for fast integration and pixelized blocks for inverse design and optimization. Some inverse design algorithms are also integrated in it like DBS (Direct Binary Search) and BBA (Binary Bat Algorithm).

The GDSII streaming is based on gdspy(https://github.com/heitzmann/gdspy) and FDTD simulation is executed on Ansys Lumerical 2020 R2.
The GDSII streaming is based on gdspy(https://github.com/heitzmann/gdspy) and FDTD simulation is executed on Ansys Lumerical.


Dependency
Expand All @@ -15,7 +15,7 @@ Dependency
- gdspy
- scipy
- numpy
- (Ansys Lumerical 2020 R2 for FDTDSimulation and MODESimulation)
- (Ansys Lumerical for FDTDSimulation and MODESimulation)

Installation
------------
Expand Down Expand Up @@ -185,6 +185,12 @@ Version 0.2.7 (Dec 16, 2021)
- New Classes for Inverse Design with Adjoint Method: ShapeOptRegion2D, ShapeOptRegion3D, TopologyOptRegion2D, TopologyOptRegion3D, AdjointForShapeOpt, AdjointForTO.


Version 0.2.8 (DEC 21, 2021)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Fix a bug for mesh region error in FDTDSimulation.
- Add draw functions for CirclePixelsRegion&RectanglePixelsRegion.
- *load_file* param for FDTDSimulation & MODESimulation.

.. |GitHub repository| image:: https://img.shields.io/badge/github-SPLayout-blue
:target: https://github.com/Hideousmon/SPLayout
.. |GitHub license| image:: https://img.shields.io/badge/lisence-GNU--3.0-green
Expand Down
2 changes: 1 addition & 1 deletion splayout/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = "0.2.7"
__version__ = "0.2.8"

from splayout.AEMDgrating import MAKE_AEMD_GRATING
from splayout.bend import Bend
Expand Down
20 changes: 12 additions & 8 deletions splayout/fdtdapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ class FDTDSimulation:
Parameters
----------
hide : Bool
Whether the Lumerical window is hidden (default is False).
Whether the Lumerical window is hidden (default: False).
fdtd_path : String
Path to the Lumerical Python API folder.
load_file : String
Path to the .fsp file that what want to be loaded (default: None).
"""
def __init__(self,hide=0,fdtd_path = "C:\\Program Files\\Lumerical\\v202\\api\\python\\"):
def __init__(self,hide=0,fdtd_path = "C:\\Program Files\\Lumerical\\v202\\api\\python\\", load_file = None):
sys.path.append(fdtd_path)
sys.path.append(os.path.dirname(__file__))
try:
Expand All @@ -30,6 +32,8 @@ def __init__(self,hide=0,fdtd_path = "C:\\Program Files\\Lumerical\\v202\\api\\p
"Lumerical FDTD is not installed in the default path, please specify the python api path with fdtd_path=***.")
self.lumapi = lumapi
self.fdtd = self.lumapi.FDTD(hide=hide)
if (type(load_file) != type(None)):
self.fdtd.eval("load(\"" + load_file + "\");")
self.global_monitor_set_flag = 0
self.global_source_set_flag = 0

Expand Down Expand Up @@ -422,7 +426,7 @@ def add_field_region(self, bottom_left_corner_point, top_right_corner_point, hei
self.fdtd.eval("set(\"override global monitor settings\",0);")
self.fdtd.eval("set(\"spatial interpolation\",\"none\");")

def add_mesh_region(self,bottom_left_corner_point,top_right_corner_point,x_mesh,y_mesh,z_mesh = 0.0025,height = 1, z_start = None, z_end = None):
def add_mesh_region(self,bottom_left_corner_point,top_right_corner_point,x_mesh,y_mesh,z_mesh = 0.0025,height = 1, z_min = None, z_max = None):
"""
Reset the mesh grid in Lumerical FDTD.
Expand All @@ -440,9 +444,9 @@ def add_mesh_region(self,bottom_left_corner_point,top_right_corner_point,x_mesh,
The grid unit in z-axis (unit: μm, default: 0.0025).
height : Float
Height of the region (in z axis, unit: μm, default: 1).
z_start : Float
z_min : Float
The start point for the structure in z axis (unit: μm, default: -0.11).
z_end : Float
z_max : Float
The end point for the structure in z axis (unit: μm, default: 0.11).
"""
self.fdtd.eval("addmesh;")
Expand All @@ -454,9 +458,9 @@ def add_mesh_region(self,bottom_left_corner_point,top_right_corner_point,x_mesh,
self.fdtd.eval("set(\"y\"," + "%.6f"%(position.y) + "e-6);")
self.fdtd.eval("set(\"y span\"," + "%.6f"%(y_span) + "e-6);")
self.fdtd.eval("set(\"z\",0);")
if (type(z_start) != type(None) and type(z_end) != type(None)):
self.fdtd.eval("set(\"z min\"," + "%.6f"%(z_start) + "e-6);")
self.fdtd.eval("set(\"z max\"," + "%.6f"%(z_end) + "e-6);")
if (type(z_min) != type(None) and type(z_max) != type(None)):
self.fdtd.eval("set(\"z min\"," + "%.6f"%(z_min) + "e-6);")
self.fdtd.eval("set(\"z max\"," + "%.6f"%(z_max) + "e-6);")
else:
self.fdtd.eval("set(\"z span\"," + "%.6f"%(height) + "e-6);")
self.fdtd.eval("set(\"dx\"," + "%.6f"%(x_mesh) + "e-6);")
Expand Down
8 changes: 6 additions & 2 deletions splayout/modeapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ class MODESimulation:
Parameters
----------
hide : Bool
Whether the Lumerical window is hidden (default is False).
Whether the Lumerical window is hidden (default: False).
fdtd_path : String
Path to the Lumerical Python API folder.
load_file : String
Path to the .lms file that what want to be loaded (default: None).
"""
def __init__(self,hide=0,fdtd_path = "C:\\Program Files\\Lumerical\\v202\\api\\python\\"):
def __init__(self,hide=0,fdtd_path = "C:\\Program Files\\Lumerical\\v202\\api\\python\\", load_file = None):
sys.path.append(fdtd_path)
sys.path.append(os.path.dirname(__file__))
try:
Expand All @@ -29,6 +31,8 @@ def __init__(self,hide=0,fdtd_path = "C:\\Program Files\\Lumerical\\v202\\api\\p
"Lumerical MODE is not installed in the default path, please specify the python api path with fdtd_path=***.")
self.lumapi = lumapi
self.mode = self.lumapi.MODE(hide=hide)
if (type(load_file) != type(None)):
self.mode.eval("load(\"" + load_file + "\");")
self.global_source_set_flag = 0
self.global_monitor_set_flag = 0

Expand Down
98 changes: 96 additions & 2 deletions splayout/pixelsregion.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from splayout.utils import *
from splayout.filledpattern import Circle,Rectangle
import numpy as np

class CirclePixelsRegion:
Expand Down Expand Up @@ -69,7 +70,7 @@ def update(self, matrix):
Parameters
----------
matrix : numpy.array
A two-dimensional binary array that represent the pixels in the region.
Array (values:0~1) that represent the pixels in the region.
'''
if (type(self.matrix_mask) != type(None)):
enable_positions = np.where(np.transpose(self.matrix_mask) == 1)
Expand Down Expand Up @@ -102,6 +103,51 @@ def update(self, matrix):
self.fdtd_engine.fdtd.eval('select("{}");'.format(self.group_name + str(position[0])+"_"+str(position[1])))
self.fdtd_engine.fdtd.eval('set("radius", %.6fe-6);'%(radius))

def draw_layout(self, matrix, cell, layer):
'''
Draw pixels on layout.
Parameters
----------
matrix : numpy.array
Array (values:0~1) that represent the pixels in the region.
cell : Cell
Cell to draw the component.
layer : Layer
Layer to draw.
'''
if (type(self.matrix_mask) != type(None)):
enable_positions = np.where(np.transpose(self.matrix_mask) == 1)
if (len(np.transpose(enable_positions)) != len(matrix)):
raise Exception("The input matrix can not match the matrix_mask!")
masked_matrix = self.matrix_mask.copy().astype(np.double)
for i,position in enumerate(np.transpose(enable_positions)):
masked_matrix[position[1], position[0]] = matrix[i]
elif (len(matrix.shape) != 2):
raise Exception("The input matrix should be two-dimensional when matrix_mask not specified!")
else:
masked_matrix = matrix

self.block_x_length = np.abs(self.left_down_point.x - self.right_up_point.x) / masked_matrix.shape[0]
self.block_y_length = np.abs(self.left_down_point.y - self.right_up_point.y) / masked_matrix.shape[1]
self.x_start_point = self.left_down_point.x + self.block_x_length / 2
self.y_start_point = self.right_up_point.y - self.block_y_length / 2

for row in range(0, masked_matrix.shape[1]):
for col in range(0, masked_matrix.shape[0]):
center_point = Point(self.x_start_point+col*self.block_x_length,self.y_start_point-row*self.block_y_length)
radius = self.pixel_radius * masked_matrix[col,row]
if (np.isclose(radius, self.pixel_radius_th) or radius < self.pixel_radius_th):
radius = 0
if (np.isclose(radius, self.pixel_radius) or radius > self.pixel_radius):
radius = self.pixel_radius
if (~np.isclose(radius, 0)):
circle = Circle(center_point=center_point, radius=radius)
circle.draw(cell,layer)





class RectanglePixelsRegion:
"""
Expand Down Expand Up @@ -183,7 +229,7 @@ def update(self, matrix):
Parameters
----------
matrix : numpy.array
A two-dimensional binary array that represent the pixels in the region.
Array (values:0~1) that represent the pixels in the region.
'''
if (type(self.matrix_mask) != type(None)):
enable_positions = np.where(np.transpose(self.matrix_mask) == 1)
Expand Down Expand Up @@ -225,4 +271,52 @@ def update(self, matrix):
self.fdtd_engine.fdtd.eval('set("x span", {:.6f}e-6);'.format(x_length))
self.fdtd_engine.fdtd.eval('set("y span", {:.6f}e-6);'.format(y_length))

def draw_layout(self, matrix, cell, layer):
'''
Draw pixels on layout.
Parameters
----------
matrix : numpy.array
Array (values:0~1) that represent the pixels in the region.
cell : Cell
Cell to draw the component.
layer : Layer
Layer to draw.
'''
if (type(self.matrix_mask) != type(None)):
enable_positions = np.where(np.transpose(self.matrix_mask) == 1)
if (len(np.transpose(enable_positions)) != len(matrix)):
raise Exception("The input matrix can not match the matrix_mask!")
masked_matrix = self.matrix_mask.copy().astype(np.double)
for i,position in enumerate(np.transpose(enable_positions)):
masked_matrix[position[1], position[0]] = matrix[i]
elif (len(matrix.shape) != 2):
raise Exception("The input matrix should be two-dimensional when matrix_mask not specified!")
else:
masked_matrix = matrix

self.block_x_length = np.abs(self.left_down_point.x - self.right_up_point.x) / masked_matrix.shape[1]
self.block_y_length = np.abs(self.left_down_point.y - self.right_up_point.y) / masked_matrix.shape[0]
self.x_start_point = self.left_down_point.x + self.block_x_length / 2
self.y_start_point = self.right_up_point.y - self.block_y_length / 2

for row in range(0, masked_matrix.shape[1]):
for col in range(0, masked_matrix.shape[0]):
center_point = Point(self.x_start_point + col * self.block_x_length,
self.y_start_point - row * self.block_y_length)
x_length = self.pixel_x_length * masked_matrix[col, row]
y_length = self.pixel_y_length * masked_matrix[col, row]
if (np.isclose(x_length, self.pixel_x_length_th) or x_length < self.pixel_x_length_th):
x_length = 0
if (np.isclose(y_length, self.pixel_y_length_th) or y_length < self.pixel_y_length_th):
y_length = 0
if (np.isclose(x_length, self.pixel_x_length) or x_length > self.pixel_x_length):
x_length = self.pixel_x_length
if (np.isclose(y_length, self.pixel_y_length) or y_length > self.pixel_y_length):
y_length = self.pixel_y_length
if (~np.isclose(x_length, 0) and ~np.isclose(y_length, 0)):
rectangle = Rectangle(center_point=center_point, width=x_length, height=y_length)
rectangle.draw(cell,layer)


0 comments on commit 9205b5c

Please sign in to comment.