Skip to content

Commit

Permalink
Version 0.3.6
Browse files Browse the repository at this point in the history
* Able to get eigenmode distribution from mode monitor.
* Enhance reliability for executing simulation.
* Figures can be shown when it is required in the inverse design regions.
* Able to get magnetic field intensity from field regions.
* Able to get power of the sources with specific wavelengths.
  • Loading branch information
Hideousmon committed Feb 13, 2022
1 parent 9465867 commit 320611f
Show file tree
Hide file tree
Showing 8 changed files with 176 additions and 17 deletions.
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,4 +196,11 @@ A polarization beam splitter inverse design example can be found [here](https://
* Alternative show for figure plot.
* Able to reset targets for adjoint methods.
* Add use('AGG') for matplotlib.
* Enhance reliability for executing simulation.
* Enhance reliability for executing simulation.

### Version 0.3.6 (Feb 12, 2022)
* Able to get eigenmode distribution from mode monitor.
* Enhance reliability for executing simulation.
* Figures can be shown when it is required in the inverse design regions.
* Able to get magnetic field intensity from field regions.
* Able to get power of the sources with specific wavelengths.
8 changes: 8 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,14 @@ Version 0.3.5 (Jan 18, 2022)
- Add use('AGG') for matplotlib.
- Enhance reliability for executing simulation.

Version 0.3.6 (Feb 12, 2022)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Able to get eigenmode distribution from mode monitor.
- Enhance reliability for executing simulation.
- Figures can be shown when it is required in the inverse design regions.
- Able to get magnetic field intensity from field regions.
- Able to get power of the sources with specific wavelengths.

.. |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
13 changes: 12 additions & 1 deletion splayout/ShapeOptRegion2D.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import os
import matplotlib
matplotlib.use('AGG')
import matplotlib.pyplot as plt

class ShapeOptRegion2D:
"""
Expand Down Expand Up @@ -170,6 +169,12 @@ def plot_epsilon_figure(self, filename = None, display = 0):
Whether to show the figure (default: 0).
"""
if (display):
matplotlib.use('module://backend_interagg')
import matplotlib.pyplot as plt
else:
import matplotlib.pyplot as plt

epsilon = np.real(np.mean(self.epsilon_figure[:,:,0,:] if type(self.epsilon_figure)!=type(None) else self.get_epsilon_distribution()[:,:,0,:], axis=-1))
xx, yy = np.meshgrid(np.linspace(self.x_positions[0], self.x_positions[-1], epsilon.shape[0]),
np.linspace(self.y_positions[0], self.y_positions[-1], epsilon.shape[1]))
Expand Down Expand Up @@ -210,6 +215,12 @@ def plot_field_figure(self, filename = None, display = 0):
Whether to show the figure (default: 0).
"""
if (display):
matplotlib.use('module://backend_interagg')
import matplotlib.pyplot as plt
else:
import matplotlib.pyplot as plt

if type(self.field_figure) != type(None):
field = np.abs(self.field_figure[:, :,0, 0, 1])
else:
Expand Down
13 changes: 12 additions & 1 deletion splayout/ShapeOptRegion3D.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import os
import matplotlib
matplotlib.use('AGG')
import matplotlib.pyplot as plt

class ShapeOptRegion3D:
"""
Expand Down Expand Up @@ -172,6 +171,12 @@ def plot_epsilon_figure(self, filename = None, display = 0):
Whether to show the figure (default: 0).
"""
if (display):
matplotlib.use('module://backend_interagg')
import matplotlib.pyplot as plt
else:
import matplotlib.pyplot as plt

epsilon = np.real(np.mean(self.epsilon_figure[:,:,int(self.z_size/2),:] if type(self.epsilon_figure)!=type(None) else self.get_epsilon_distribution()[:,:,int(self.z_size/2),:], axis=-1))
xx, yy = np.meshgrid(np.linspace(self.x_positions[0], self.x_positions[-1], epsilon.shape[0]),
np.linspace(self.y_positions[0], self.y_positions[-1], epsilon.shape[1]))
Expand Down Expand Up @@ -212,6 +217,12 @@ def plot_field_figure(self, filename = None, display = 0):
Whether to show the figure (default: 0).
"""
if (display):
matplotlib.use('module://backend_interagg')
import matplotlib.pyplot as plt
else:
import matplotlib.pyplot as plt

if type(self.field_figure) != type(None):
field = np.abs(self.field_figure[:, :,int(self.z_size/2), 0, 1])
else:
Expand Down
13 changes: 12 additions & 1 deletion splayout/TopologyOptRegion2D.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import os
import matplotlib
matplotlib.use('AGG')
import matplotlib.pyplot as plt

class TopologyOptRegion2D:
"""
Expand Down Expand Up @@ -194,6 +193,12 @@ def plot_epsilon_figure(self, filename = None, display = 0):
Whether to show the figure (default: 0).
"""
if (display):
matplotlib.use('module://backend_interagg')
import matplotlib.pyplot as plt
else:
import matplotlib.pyplot as plt

epsilon = np.real(np.mean(self.epsilon_figure[:,:,0,:] if type(self.epsilon_figure)!=type(None) else self.get_epsilon_distribution()[:,:,0,:], axis=-1))
xx, yy = np.meshgrid(np.linspace(self.x_positions[0], self.x_positions[-1], epsilon.shape[0]),
np.linspace(self.y_positions[0], self.y_positions[-1], epsilon.shape[1]))
Expand Down Expand Up @@ -234,6 +239,12 @@ def plot_field_figure(self, filename = None, display = 0):
Whether to show the figure (default: 0).
"""
if (display):
matplotlib.use('module://backend_interagg')
import matplotlib.pyplot as plt
else:
import matplotlib.pyplot as plt

field = np.abs(np.mean(self.field_figure[:, :, 0, 0, :], axis=-1) if type(self.epsilon_figure) != type(
None) else np.mean(self.get_E_distribution()[:, :, 0, 0, :], axis=-1))
xx, yy = np.meshgrid(np.linspace(self.x_positions[0], self.x_positions[-1], field.shape[0]),
Expand Down
14 changes: 13 additions & 1 deletion splayout/TopologyOptRegion3D.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import os
import matplotlib
matplotlib.use('AGG')
import matplotlib.pyplot as plt



class TopologyOptRegion3D:
Expand Down Expand Up @@ -195,6 +195,12 @@ def plot_epsilon_figure(self, filename = None, display = 0):
Whether to show the figure (default: 0).
"""
if (display):
matplotlib.use('module://backend_interagg')
import matplotlib.pyplot as plt
else:
import matplotlib.pyplot as plt

epsilon = np.real(np.mean(self.epsilon_figure[:,:,int(self.z_size/2),:] if type(self.epsilon_figure)!=type(None) else self.get_epsilon_distribution()[:,:,int(self.z_size/2),:], axis=-1))
xx, yy = np.meshgrid(np.linspace(self.x_positions[0], self.x_positions[-1], epsilon.shape[0]),
np.linspace(self.y_positions[0], self.y_positions[-1], epsilon.shape[1]))
Expand Down Expand Up @@ -235,6 +241,12 @@ def plot_field_figure(self, filename = None, display = 0):
Whether to show the figure (default: 0).
"""
if (display):
matplotlib.use('module://backend_interagg')
import matplotlib.pyplot as plt
else:
import matplotlib.pyplot as plt

field = np.abs(np.mean(self.field_figure[:, :, int(self.z_size/2), 0, :], axis=-1) if type(self.field_figure) != type(
None) else np.mean(self.get_E_distribution()[:, :, int(self.z_size/2), 0, :], axis=-1))
xx, yy = np.meshgrid(np.linspace(self.x_positions[0], self.x_positions[-1], field.shape[0]),
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.3.5"
__version__ = "0.3.6"

from splayout.AEMDgrating import MAKE_AEMD_GRATING
from splayout.bend import Bend
Expand Down
121 changes: 110 additions & 11 deletions splayout/fdtdapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -503,24 +503,19 @@ def save(self,filename="temp"):
self.fdtd.save(filename)


def run(self,filename="temp", min_time_threshold = 3):
def run(self,filename="temp"):
"""
Save the simulation as a ".fsp" file and run.
Parameters
----------
filename : String
File name or File path (default: "temp").
min_time_threshold : Float or Int
The minimum time for a possible simulation.
"""
self.save(filename)
self.fdtd.eval("switchtolayout;")
time_consumption = 0
while (time_consumption < min_time_threshold):
time_before_sim = time.perf_counter()
while(self.fdtd.layoutmode()):
self.fdtd.eval("run;")
time_consumption = time.perf_counter() - time_before_sim


def get_transmission(self,monitor_name,datafile = None):
Expand Down Expand Up @@ -614,6 +609,68 @@ def get_mode_phase(self, expansion_name, direction = FORWARD, datafile = None):
np.save(datafile, mode_phase.flatten())
return mode_phase.flatten()

def get_mode_eigen_E(self, expansion_name, mode_number, if_get_spatial = 0, datafile = None):
"""
Get electric field distribution of the eigenmode from mode expansion monitor.
Parameters
----------
expansion_name : String
Name of the mode expansion monitor.
mode_number : Int
The selected mode index (start from 1).
if_get_spatial : Bool
Whether get spatial information as return (default: 0).
datafile : String
The name of the file for saving the data, None means no saving (default: None).
out : Array
if if_get_spatial == 0: field
size: (x mesh, y mesh, z mesh, frequency points, 3).
if if_get_spatial == 1: field, x mesh, y mesh, z mesh
size: (x mesh, y mesh, z mesh, frequency points, 3), (x mesh,), (y mesh,), (z mesh,)
"""
mode_profile = self.fdtd.getresult(expansion_name, "mode profiles")
if (datafile != None):
np.save(datafile, mode_profile['E'+str(mode_number)])
if if_get_spatial:
return mode_profile['E'+str(mode_number)],mode_profile['x'].flatten(),mode_profile['y'].flatten(),mode_profile['z'].flatten()
else:
return mode_profile['E'+str(mode_number)]



def get_mode_eigen_H(self, expansion_name, mode_number, if_get_spatial = 0,datafile = None):
"""
Get magnetic field distribution of the eigenmode from mode expansion monitor.
Parameters
----------
expansion_name : String
Name of the mode expansion monitor.
mode_number : Int
The selected mode index (start from 1).
if_get_spatial : Bool
Whether get spatial information as return (default: 0).
datafile : String
The name of the file for saving the data, None means no saving (default: None).
out : Array
if if_get_spatial == 0: field
size: (x mesh, y mesh, z mesh, frequency points, 3).
if if_get_spatial == 1: field, x mesh, y mesh, z mesh
size: (x mesh, y mesh, z mesh, frequency points, 3), (x mesh,), (y mesh,), (z mesh,)
"""
mode_profile = self.fdtd.getresult(expansion_name, "mode profiles")
if (datafile != None):
np.save(datafile, mode_profile['H' + str(mode_number)])
if if_get_spatial:
return mode_profile['H' + str(mode_number)], mode_profile['x'].flatten(), mode_profile['y'].flatten(), \
mode_profile['z'].flatten()
else:
return mode_profile['H' + str(mode_number)]


def get_mode_coefficient(self, expansion_name , direction = FORWARD, datafile = None):
"""
Get data and calculate coefficient from mode expansion monitor after running the simulation.
Expand Down Expand Up @@ -645,7 +702,7 @@ def get_mode_coefficient(self, expansion_name , direction = FORWARD, datafile =
np.save(datafile, mode_coefficient.flatten())
return mode_coefficient.flatten()

def get_source_power(self, source_name=None, datafile = None):
def get_source_power(self, source_name=None, wavelengths = None,datafile = None):
"""
Get source power spectrum from source.
Expand All @@ -665,7 +722,15 @@ def get_source_power(self, source_name=None, datafile = None):
-----
This function should be called after setting the frequency points in any frequency domain monitor.
"""
if self.global_source_set_flag and self.global_monitor_set_flag:
if type(wavelengths) != type(None):
frequency = scipy.constants.speed_of_light / np.array([wavelengths]).flatten()
if (type(source_name) == type(None)):
source_power = self.fdtd.sourcepower(frequency)
else:
self.lumapi.putMatrix(self.fdtd.handle, "frequency", frequency)
self.fdtd.eval("data = sourcepower(frequency,2,\""+source_name+"\");")
source_power = self.lumapi.getVar(self.fdtd.handle, varname="data")
elif self.global_source_set_flag and self.global_monitor_set_flag:
wavelength = np.linspace(self.wavelength_start, self.wavelength_end, self.frequency_points)
frequency = scipy.constants.speed_of_light / wavelength
if (type(source_name) == type(None)):
Expand All @@ -680,6 +745,8 @@ def get_source_power(self, source_name=None, datafile = None):
np.save(datafile, source_power.flatten())
return np.asarray(source_power).flatten()



def get_wavelength(self):
"""
Get wavelength points from Lumerical simulation.
Expand Down Expand Up @@ -795,7 +862,7 @@ def get_epsilon_distribution_in_CAD(self,index_monitor_name="index", data_name =
"clear({0}_data_set);".format(index_monitor_name))
return data_name

def get_E_distribution(self, field_monitor_name = "field", data_name = "field_data",datafile = None, if_get_spatial = 0):
def get_E_distribution(self, field_monitor_name = "field", data_name = "field_data_E",datafile = None, if_get_spatial = 0):
"""
Get electric field distribution from field monitor.
Expand All @@ -804,7 +871,7 @@ def get_E_distribution(self, field_monitor_name = "field", data_name = "field_da
field_monitor_name : String
Name of the field monitor (default: "field").
data_name : String
Name of the data in Lumeircal FDTD (default: "field_data").
Name of the data in Lumeircal FDTD (default: "field_data_E").
datafile : String
The name of the file for saving the data, None means no saving (default: None).
if_get_spatial : Bool
Expand All @@ -827,6 +894,38 @@ def get_E_distribution(self, field_monitor_name = "field", data_name = "field_da
else:
return field['E']

def get_H_distribution(self, field_monitor_name = "field", data_name = "field_data_H",datafile = None, if_get_spatial = 0):
"""
Get magnetic field distribution from field monitor.
Parameters
----------
field_monitor_name : String
Name of the field monitor (default: "field").
data_name : String
Name of the data in Lumeircal FDTD (default: "field_data_H").
datafile : String
The name of the file for saving the data, None means no saving (default: None).
if_get_spatial : Bool
Whether get spatial information as return (default: 0).
Returns
-------
out : Array
if if_get_spatial == 0: field
size: (x mesh, y mesh, z mesh, frequency points, 3).
if if_get_spatial == 1: field, x mesh, y mesh, z mesh
size: (x mesh, y mesh, z mesh, frequency points, 3), (x mesh,), (y mesh,), (z mesh,)
"""
self.fdtd.eval("{0} = getresult(\"".format(data_name) + field_monitor_name + "\",\"H\");")
field = self.lumapi.getVar(self.fdtd.handle, "{0}".format(data_name))
if (datafile != None):
np.save(datafile, field['H'])
if if_get_spatial:
return field['H'],field['x'].flatten(),field['y'].flatten(),field['z'].flatten()
else:
return field['H']

def get_E_distribution_in_CAD(self, field_monitor_name = "field", data_name = "field_data"):
"""
Get electric field distribution from field monitor and save the data in CAD.
Expand Down

0 comments on commit 320611f

Please sign in to comment.