"""Contains the class :class:`.Nothing` which represents an empty/null point in a
configuration."""
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 NothingWorkspace(ConnectorWorkspace):
def __init__(self, owner, sim):
super().__init__(owner, sim, False, False)
[docs]class Nothing(Connector):
"""Represents an empty point in the interferometer configuration.
`Nothing` is just some point in space that can be connected to. For example, you can use this to
propagate a beam from some component out to some arbitrary point to make a measurement at. You
can also use this to split spaces up, if you wanted to measure something inbetween two
components. It can also be used to replace a component, for example if you want to remove a lens
or a mirror in some beam path.
Parameters
----------
name : str
Name of newly created nothing.
"""
def __init__(self, name):
super().__init__(name)
# 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 = NothingWorkspace(self, sim)
ws.I = np.eye(sim.model_settings.num_HOMs, dtype=np.complex128)
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)