Home › Forums › Nazca › Create trial cells when using minimizer algorithm? › Reply To: Create trial cells when using minimizer algorithm?
The below MZI example in demofab may contain what you are looking for.
A root-solver optimizes the MZI for a specific target geometrical path length difference. The MZI method behaves either like a function to optimize for a path length difference in the root-solver, or it returns a Nazca Cell. In the former case it deletes all cells generated in the call; Particularly related to your question, I create sets S1 and S2 from dict nd.cfg.cellnames just before and just after a cell iteration. This dict is leading in tracking cell warnings etc., and popping the new cells S2 – S1 will make Nazca forget about them.
The example here uses the “trace” module for measuring geometrical interconnect length, but this concept also can be exploited in a more fancy way utilizing the pathfinder module and compact models, which is something that would need dedicated tutorials.
As for your radius question, interconnects do have a build-in minimum radius check option, which is based on the xsection.minimum_radius attribute of the xs you assign to the interconnect.
from functools import partial from scipy.optimize import fsolve import nazca as nd import nazca.demofab as demo def cell_to_solve(offset=10, target_diff=20, cell=False): """Create a temporary MZI cell to return the arm length difference or return the Cell. Free parameter here is the sbend offset. Args: cell (bool): False: return distance from target; True: Return MZI cell. Returns: Cell | float: """ if not cell: S1 = set(nd.cfg.cellnames.keys()) with nd.Cell('test') as C: m1 = demo.mmi1x2_dp().put(0) nd.trace.trace_start() demo.deep.sbend(offset=offset).put(m1.pin['b0']) demo.deep.sbend(offset=-offset).put() nd.trace.trace_stop() L1 = nd.trace.trace_length() m2 = demo.mmi2x2_dp().put() nd.trace.trace_start() demo.deep.sbend_p2p(pin1=m1.pin['b1'], pin2=m2.pin['a1']).put() nd.trace.trace_stop() L2 = nd.trace.trace_length() diff = L1 - L2 if cell: return C else: S2 = set(nd.cfg.cellnames.keys()) for dS in S2 - S1: nd.cfg.cellnames.pop(dS) return diff - target_diff def find_MZI_solution(target_diff, initial_offset): """Find an optimized offset to reach the target-diff in the MZI using a standard root solver. Args: target_diff (float): target armlength difference in MZI inititial_offset (float): starting offset to find a solution """ func = partial(cell_to_solve, target_diff=target_diff) root = fsolve(func, [initial_offset]) return func(offset=root, cell=True) MZI = find_MZI_solution(target_diff=50, initial_offset=70) nd.export_png(MZI)