Optimization#

class lumopt2.core.optimization.Optimization(project, optimizer, callbacks=None, store_all_simulations=False, log_profiling_summary=False)#

Coordinates the optimization workflow for photonic inverse design.

This class manages the interaction between a Project (which handles simulation and gradient computation) and an Optimizer (which performs the parameter updates). It handles different optimization flows for topology optimization and shape optimization.

Parameters:
projectProject

The project instance containing the simulation setup, FOM definition, and parametrization. Must have methods for computing FOM and gradients.

optimizerBaseOptimizer

The optimizer instance that will perform the parameter updates. Must have an optimize method that accepts objective and gradient functions.

callbackslist of BaseCallback, optional

List of callbacks invoked at the standard optimization events (on_optimization_start, on_iteration_start, on_function_eval, on_iteration_end, on_optimization_end). A single callback may be passed in place of a list. All visualization is performed via callbacks; pass an instance of lumopt2.utils.GraphicalVisualizer to monitor optimization progress with live plots. If None (the default), a lumopt2.utils.FileLogger is installed automatically so that every run produces an optimization.log in the project folder. Pass an empty list ([]) to disable callbacks entirely.

store_all_simulationsbool, optional

If True, each iteration writes uniquely-named .fsp files (fwd_default_iter1.fsp, fwd_default_iter2.fsp, …) so the full simulation history is preserved on disk. If False (default), the .fsp filenames stay stable across iterations (fwd_default.fsp, adj_default_<monitor>.fsp) so each new forward simulation overwrites the previous one in place. Stable names also mean the visualizer can reload the most recent forward .fsp without ever renaming it on disk – renaming the file would invalidate Lumerical’s internal pointer to its sibling <stem>_output.h5 and break port-derived results like T.

log_profiling_summarybool, optional

If True, the wall-clock profiling summary (FDTD setup, simulation, dEps/dP, data transfer, …) is printed at INFO level when the optimization finishes. If False (default), the summary is still emitted at DEBUG so it remains available when the user enables verbose logging, but does not clutter standard INFO output. Users who want the summary on demand can also call lumopt2.profiler.log_summary() directly at any time.

Attributes:
projectProject

Reference to the project being optimized.

optimizerBaseOptimizer

Reference to the optimizer performing updates.

iterationint

Current iteration number. Iteration 0 corresponds to the baseline evaluation at the initial parameters; iterations 1, 2, … correspond to the optimizer’s parameter updates.

fom_eval_countint

Total number of FOM evaluations performed so far (1-indexed). Each cache miss increments this counter.

grad_eval_countint

Total number of gradient evaluations performed so far (1-indexed). Each call to Project.compute_gradient() that is not served by the per-evaluation cache increments this counter. Together with fom_eval_count it lets callbacks distinguish FOM-only line-search trials from full forward+adjoint passes.

best_fomfloat or None

Best (maximum) FOM value encountered during optimization.

best_paramsnp.ndarray or None

Parameters corresponding to the best FOM value.

Raises:
ValueError

If project or optimizer is None or invalid.

TypeError

If project is not an instance of Project.

TypeError

If optimizer is not an instance of BaseOptimizer.

TypeError

If project doesn’t have required methods (compute_fom, compute_gradient).

Notes

The Optimization class automatically determines the optimization type based on the parametrization in the project:

  • Topology: Uses density-based topology optimization

  • Parametrization: Uses shape optimization with user-defined parameter mappings

  • ClosedCurve: Uses shape optimization with Bezier curve control points

Unrecognised parametrization types raise TypeError.

The class tracks the best FOM and parameters throughout optimization, regardless of whether the optimizer converges or terminates early.

Examples

Basic topology optimization:

>>> project = lmpt.Project(
...     setup=setup_script,
...     fom=fom,
...     parametrization=topology,
...     fdtd_session=session
... )
>>> optimizer = lmpt.ScipyOptimizer(method='L-BFGS-B', max_iter=50)
>>> opt = lmpt.Optimization(project, optimizer)
>>> final_params, final_fom = opt.run()

With bounds for topology optimization:

>>> bounds = [(0, 1) for _ in range(n_pixels)]
>>> optimizer = lmpt.ScipyOptimizer(method='L-BFGS-B', bounds=bounds)
>>> opt = lmpt.Optimization(project, optimizer)
>>> final_params, final_fom = opt.run()

Methods

Optimization.get_history()

Get the optimization history from the optimizer.

Optimization.get_optimization_type()

Determine the type of optimization being performed.

Optimization.prepare_optimization([...])

Validate inputs and reset per-run state for an optimization run.

Optimization.run([initial_params, callback])

Run the optimization workflow.