Source code for finesse.components.telescope

import numpy as np
from finesse.components.general import Connector, InteractionType
from finesse.components.node import NodeType, NodeDirection
from finesse.components.workspace import ConnectorWorkspace


[docs]class TelescopeWorkspace(ConnectorWorkspace): def __init__(self, owner, sim): super().__init__(owner, sim, False, False)
# IMPORTANT: renaming this class impacts the katscript spec and should be avoided!
[docs]class Telescope(Connector): """This component represents a perfectly matching and adapting telescope. It will not change the beam parameter on transmission of the component and any field coming in will be transmitted to the other side into the other beam parameter. This should be used in cases when you want to connect to optical systems but do not want to design a complicated optical telescope system to mode-match them both, or in cases where one system has a changing parameter but you don't care about the details of the telescope. No beam is traced through the telescope so you must specify a beam parameter or a cavity on both sides of the telescope. If not, a tracing error will occur. Currently no losses, mismatch, or misalignments can be induced at this telescope. There is no accumulated Gouy phase or plane-wave propagation phase. Parameters ---------- name : str Name of newly created telescope """ def __init__(self, name): super().__init__(name) # This is usually True, but we don't want any tracing to happen through # this component so that either side is not affected by optical systems # on the other side. This is important for the telescope to be # perfectly matching and adapting. self._trace_through = False # Here we register that fact this component will # want to have some ports and nodes as well as # the couplings between them self._add_port("p1", NodeType.OPTICAL) # front self._add_port("p2", NodeType.OPTICAL) # back # input and output optical fields at port 1 (Front face) self.p1._add_node("i", NodeDirection.INPUT) self.p1._add_node("o", NodeDirection.OUTPUT) # input and output optical fields at port 2 (Back face) self.p2._add_node("i", NodeDirection.INPUT) self.p2._add_node("o", NodeDirection.OUTPUT) # Optic to optic couplings self._register_node_coupling( "P1i_P2o", self.p1.i, self.p2.o, interaction_type=InteractionType.TRANSMISSION, ) self._register_node_coupling( "P2i_P1o", self.p2.i, self.p1.o, interaction_type=InteractionType.TRANSMISSION, ) def _get_workspace(self, sim): ws = TelescopeWorkspace(self, sim) ws.I = np.eye(sim.model_settings.num_HOMs, dtype=np.complex128) # It is never changing as there is currently no mismatch # or misalignment in the telescope, if this ever changes # it needs to be updated ws.carrier.add_fill_function(self._fill_carrier, False) ws.signal.add_fill_function(self._fill_signal, False) return ws def _fill_optical_matrix(self, ws, matrix, connections): for freq in matrix.optical_frequencies.frequencies: with matrix.component_edge_fill3( ws.owner_id, connections.P1i_P2o_idx, freq.index, freq.index, ) as mat: mat[:] = ws.I with matrix.component_edge_fill3( ws.owner_id, connections.P2i_P1o_idx, freq.index, freq.index, ) as mat: mat[:] = ws.I def _fill_carrier(self, ws): self._fill_optical_matrix(ws, ws.sim.carrier, ws.carrier.connections) def _fill_signal(self, ws): self._fill_optical_matrix(ws, ws.sim.signal, ws.signal.connections)