Skip to content

Commit

Permalink
Updated Docs and Recycle FDTD session
Browse files Browse the repository at this point in the history
-The docs have been updated for the broadband figure of merit. Please
note that there is an API change and old code using lumopt will need to
be updated to run. This involves adding some new arguments when defining
a ModeMatch object to define the broaband target function.
-The FDTD Solutions session is recycled so only one session per
optimization is created. This improved performance by avoiding the load
time for the application

This commit corresponds to the lumopt version packaged inside FDTD
Solutions 2019a R4 (8.21.1882)
  • Loading branch information
areid-van committed Feb 28, 2019
1 parent 8f779f8 commit 93094d4
Show file tree
Hide file tree
Showing 18 changed files with 252 additions and 318 deletions.
2 changes: 1 addition & 1 deletion docs/all_others.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Fields
Gradient Fields
===============

.. autoclass:: lumopt.utilities.gradients.Gradient_fields
.. autoclass:: lumopt.utilities.gradients.GradientFields
:members:

Others
Expand Down
6 changes: 0 additions & 6 deletions docs/foms.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,3 @@ Figures of Merit

.. autoclass:: lumopt.figures_of_merit.modematch.ModeMatch


.. autoclass:: lumopt.figures_of_merit.field_intensities.FieldIntensity


.. autoclass:: lumopt.figures_of_merit.field_intensities.FieldIntensities

2 changes: 1 addition & 1 deletion docs/geometries.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ Geometries

.. autoclass:: lumopt.geometries.polygon.Polygon

.. autoclass:: lumopt.geometries.polygon.function_defined_Polygon
.. autoclass:: lumopt.geometries.polygon.FunctionDefinedPolygon
1 change: 0 additions & 1 deletion docs/materials.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,3 @@ Materials
=========

.. autoclass:: lumopt.utilities.materials.Material
:members:
4 changes: 1 addition & 3 deletions docs/optimization.rst
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
Optimization
============

.. autoclass:: lumopt.optimization.Super_Optimization

.. autoclass:: lumopt.optimization.SuperOptimization

.. autoclass:: lumopt.optimization.Optimization
:members: run
7 changes: 3 additions & 4 deletions docs/optimizers.rst
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
Optimizers
==========

.. autoclass:: lumopt.optimizers.generic_optimizers.FixedStepGradientDescent


.. autoclass:: lumopt.optimizers.generic_optimizers.ScipyOptimizers

.. autoclass:: lumopt.optimizers.generic_optimizers.Adaptive_Gradient_Descent
.. autoclass:: lumopt.optimizers.fixed_step_gradient_descent.FixedStepGradientDescent

.. autoclass:: lumopt.optimizers.adaptive_gradient_descent.AdaptiveGradientDescent
4 changes: 2 additions & 2 deletions docs/user_facing.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
User Functions
==============
User Classes and Functions
==========================

.. toctree::
:maxdepth: 2
Expand Down
27 changes: 16 additions & 11 deletions lumopt/figures_of_merit/modematch.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,24 @@

class ModeMatch(object):

""" Figure of Merit class based on the overlap integral between the fields recorded by a DFT monitor and the selected mode.
The class adds a mode expansion monitor to the simulation and links it to the provided DFT monitor. The mode expansion
monitor is used to retrieve the overlap result once the provided simulation has run. The overlap integral is that of
equation (7) of `https://doi.org/10.1364/OE.21.021693`, which is equivalent to the overlap integral built into FDTD and
described in `https://kb.lumerical.com/ref_sim_obj_using_mode_expansion_monitors.html`.
""" Calculates the figure of merit from an overlap integral between the fields recorded by a field monitor and the slected mode.
A mode expansion monitor is added to the field monitor to calculate the overlap result, which appears as T_forward in the
list of mode expansion monitor results. The T_forward result is described in the following page:
https://kb.lumerical.com/ref_sim_obj_using_mode_expansion_monitors.html
This result is equivalent to equation (7) in the following paper:
C. Lalau-Keraly, S. Bhargava, O. Miller, and E. Yablonovitch, "Adjoint shape optimization applied to electromagnetic design,"
Opt. Express 21, 21693-21701 (2013). https://doi.org/10.1364/OE.21.021693
Parameters
----------
:param monitor_name: name of the DFT monitor that records the fields to be used in the mode overlap calculation.
:param mode_number: selected mode in the list generated by the mode expansion monitor.
:param direction: direction of propagation of the mode injected by the source.
:target_T_fwd: function describing the target T_forward (provided by mode expansion monitors); used to generate the FOM.
:norm_p: exponent of the p-norm used to generate the figure of merit; use to generate the FOM.
:param monitor_name: name of the field monitor that records the fields to be used in the mode overlap calculation.
:param mode_number: mode number in the list of modes generated by the mode expansion monitor.
:param direction: direction of propagation ('Forward' or 'Backward') of the mode injected by the source.
:param target_T_fwd: function describing the target T_forward vs wavelength (see documentation for mode expansion monitors).
:param norm_p: exponent of the p-norm used to generate the figure of merit; use to generate the FOM.
"""

def __init__(self, monitor_name, mode_number, direction, target_T_fwd = lambda wl: np.ones(wl.size), norm_p = 1):
Expand Down
132 changes: 59 additions & 73 deletions lumopt/geometries/polygon.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,44 +12,34 @@


class Polygon(Geometry):
'''An polygon extruded in the z direction, where the points are allowed to move in any direction in the x-y plane. The points
and extrusion parameters must be defined, as well as the permittivity (or material) forming the inside of the polygon and the permittivity
(or material) surrounding the polygon. If the Polygon is surrounded by different materials, the shape derivatives will be wrong along the edges
where the wrong material surrounds the polygon.
:param points:
The points are defined as a numpy array of tupple coordinates np.array([(x0,y0),...,(xn,yn)]). THEY MUST BE DEFINED IN A
COUNTER CLOCKWISE DIRECTION.
:param z:
The center of the polygon along the z axis
:param depth:
The depth of the extrusion in the z direction (in meters)
:param eps_out:
The permittivity of the outer-material (square of refractive index), or the name of a Lumerical Material, from which the permittivity
will be extracted. Can also be a Material object from :class:`lumpot.utilities.materials.Material` with a defined mesh order.
:param eps_in:
The permittivity of the inner-material (square of refractive index), or the name of a Lumerical Material, from which the permittivity
will be extracted. Can also be a Material object from :class:`lumpot.utilities.materials.Material` with a defined mesh order.
:param edge_precision:
The edges will be discretized when calculating the gradients with respect to moving different points of the geometry. This parmeter
will define the number of discretization points per edge. It is strongly recommended to have at least a few points per mesh cell.
'''

self_update=False

def __init__(self,points, z, depth, eps_out, eps_in, edge_precision, bounds, dx):
self.points=points
self.z=z
self.depth=depth
self.gradients=[]
self.edge_precision=edge_precision
self.dx=dx
"""
Defines a polygon with vertices on the (x,y)-plane that are extruded along the z direction to create a 3-D shape. The vertices are
defined as a numpy array of coordinate pairs np.array([(x0,y0),...,(xn,yn)]). THE VERTICES MUST BE ORDERED IN A COUNTER CLOCKWISE DIRECTION.
:param points: array of shape (N,2) defining N polygon vertices.
:param z: center of polygon along the z-axis.
:param depth: span of polygon along the z-axis.
:param eps_out: permittivity of the material around the polygon.
:param eps_in: permittivity of the polygon material.
:param edge_precision: number of quadrature points along each edge for computing the FOM gradient using the shape derivative approximation method.
"""

def __init__(self, points, z, depth, eps_out, eps_in, edge_precision):
self.points = points
self.z = float(z)
self.depth = float(depth)
self.edge_precision = int(edge_precision)
self.eps_out = eps_out if isinstance(eps_out, Material) else Material(eps_out)
self.eps_in = eps_in if isinstance(eps_in, Material) else Material(eps_in)

if self.depth <= 0.0:
raise UserWarning("polygon depth must be positive.")
if self.edge_precision <= 0:
raise UserWarning("edge precision must be a positive integer.")

self.gradients = list()
self.make_edges()
self.hash = random.getrandbits(64)
return

def make_edges(self):
'''Creates all the edge objects'''
Expand Down Expand Up @@ -132,45 +122,41 @@ def plot(self,ax):


class FunctionDefinedPolygon(Polygon):
'''This defines a polygon from a function that takes the optimization parameters and returns a set of points.
:param func:
A function that takes as input a list of optimization parameters and returns a list of point coordinates forming
the polygon to optimize. See example :func:`~lumpot.geometries.polygon.taper_splitter`.
The points are defined as a numpy array of tupple coordinates np.array([(x0,y0),...,(xn,yn)]).
THEY MUST BE DEFINED IN A COUNTER CLOCKWISE DIRECTION.
:param initial_params:
The initial parameters, which when fed to the previously defined function, will generate the starting geometry of
the optimization
:param Bounds:
The bounds that should be applied on the optimization parameters
:param z:
see :class:`~lumpot.geometries.polygon.Polygon`
:param depth:
see :class:`~lumpot.geometries.polygon.Polygon`
:param eps_out:
see :class:`~lumpot.geometries.polygon.Polygon`
:param eps_in:
see :class:`~lumpot.geometries.polygon.Polygon`
:param edge_precision:
see :class:`~lumpot.geometries.polygon.Polygon`
'''

def __init__(self, func, initial_params, bounds, z, depth, eps_out, eps_in, edge_precision, dx):
self.points=func(initial_params)
self.func=func
self.z=z
self.current_params=initial_params
self.depth=depth
self.gradients=[]
self.edge_precision=edge_precision
self.bounds=bounds
self.params_hist=[initial_params]
self.eps_out = eps_out if isinstance(eps_out, Material) else Material(eps_out)
self.eps_in = eps_in if isinstance(eps_in, Material) else Material(eps_in)
self.make_edges()
self.dx=dx
self.hash = random.getrandbits(128)
"""
Constructs a polygon from a user defined function that takes the optimization parameters and returns a set of vertices defining a polygon.
The polygon vertices returned by the function must be defined as a numpy array of coordinate pairs np.array([(x0,y0),...,(xn,yn)]). THE
VERTICES MUST BE ORDERED IN A COUNTER CLOCKWISE DIRECTION.
Parameters
----------
:param fun: function that takes the optimization parameter values and returns a polygon.
:param initial_params: initial optimization parameter values.
:param bounds: bounding ranges (min/max pairs) for each optimization parameter.
:param z: center of polygon along the z-axis.
:param depth: span of polygon along the z-axis.
:param eps_out: permittivity of the material around the polygon.
:param eps_in: permittivity of the polygon material.
:param edge_precision: number of quadrature points along each edge for computing the FOM gradient using the shape derivative approximation method.
:param dx: step size for computing the FOM gradient using permittivity perturbations.
"""

def __init__(self, func, initial_params, bounds, z, depth, eps_out, eps_in, edge_precision = 5, dx = 1.0e-10):
self.func = func
self.current_params = initial_params
points = func(initial_params)
super(FunctionDefinedPolygon, self).__init__(points, z, depth, eps_out, eps_in, edge_precision)
self.bounds = bounds
self.dx = float(dx)

if len(self.bounds) != self.current_params.size:
raise UserWarning("there must be one bound for each parameter.")
for bound in self.bounds:
if bound[1] - bound[0] <= 0.0:
raise UserWarning("bound ranges must be positive.")
if self.dx <= 0.0:
raise UserWarning("step size must be positive.")

self.params_hist = list(initial_params)

def update_geometry(self,params):
self.points=self.func(params)
Expand Down
Loading

0 comments on commit 93094d4

Please sign in to comment.