Commit 89b56567 authored by Samuel Rowlinson's avatar Samuel Rowlinson
Browse files

Merge branch 'master' of git.ligo.org:finesse/finesse3

parents eafcd972 bccf5fc6
......@@ -146,6 +146,7 @@ def ext_modules():
("knm.pyx", open_mp_args),
("components/workspace.pyx", {}),
("components/mechanical.pyx", {}),
("components/modal/workspace.pyx", {}),
("components/modal/mirror.pyx", {}),
("components/modal/beamsplitter.pyx", {}),
("components/modal/signal.pyx", {}),
......
......@@ -12,7 +12,6 @@ from finesse.utilities import refractive_index
from finesse.components.general import InteractionType
from finesse.components.surface import Surface
from finesse.components.node import NodeDirection, NodeType
LOGGER = logging.getLogger(__name__)
......@@ -107,13 +106,6 @@ class Beamsplitter(Surface):
mass=np.inf,
signal_gain=1e-9,
):
from finesse.components.modal.beamsplitter import BeamsplitterConnections
# NOTE this is needed (for now) as it is used in _check_phi which is currently called
# in Surface constructor when initialising phi value
self._cos_alpha = 1
self._cos_alpha_2 = 1
super().__init__(
name,
R,
......@@ -125,8 +117,9 @@ class Beamsplitter(Surface):
ybeta,
mass,
signal_gain,
BeamsplitterConnections,
)
self._cos_alpha = 1
self._cos_alpha_2 = 1
self._add_port("p1", NodeType.OPTICAL)
self.p1._add_node("i", NodeDirection.INPUT)
......@@ -240,7 +233,7 @@ class Beamsplitter(Surface):
nr1 = refractive_index(from_node, symbolic=True) or 1
nr2 = refractive_index(to_node, symbolic=True) or 1
alpha1 = np.radians(alpha)
# we get alpha2 from Snell's law
if from_node.port is self.p3 or from_node.port is self.p4:
......
......@@ -179,12 +179,11 @@ class Connector(ModelElement):
_borrows_nodes = False
def __init__(self, name, connections_type=None):
def __init__(self, name):
from finesse.components.workspace import Connections
super().__init__(name)
self.__connections_type = connections_type or Connections
self.__connections = OrderedDict()
self.__ports = OrderedDict()
self.__interaction_types = {}
......@@ -202,10 +201,6 @@ class Connector(ModelElement):
def __nodes_of(self, node_type):
return tuple([node for node in self.nodes.values() if node.type == node_type])
@property
def connections_type(self):
return self.__connections_type
@property
def optical_nodes(self):
"""The optical nodes stored by the connector.
......
......@@ -7,8 +7,7 @@ import logging
import numpy as np
from finesse.components.modal.isolator import (
IsolatorWorkspace,
IsolatorConnections,
IsolatorWorkspace
)
from finesse.components.general import Connector, InteractionType
from finesse.components.node import NodeDirection, NodeType
......@@ -32,7 +31,7 @@ class Isolator(Connector):
"""
def __init__(self, name, S=0.0):
super().__init__(name, IsolatorConnections)
super().__init__(name)
self.S = S
......
......@@ -7,8 +7,7 @@ import logging
import numpy as np
from finesse.components.modal.lens import (
LensWorkspace,
LensConnections,
LensWorkspace
)
from finesse.components.general import Connector, InteractionType
from finesse.components.node import NodeDirection, NodeType
......@@ -46,7 +45,7 @@ class Lens(Connector):
"""
def __init__(self, name, f=np.inf):
super().__init__(name, LensConnections)
super().__init__(name)
self.f = f
......
......@@ -12,7 +12,6 @@ from finesse.utilities import refractive_index
from finesse.components.modal.mirror import (
mirror_fill,
MirrorWorkspace,
MirrorConnections,
)
from finesse.components.general import InteractionType
from finesse.components.surface import Surface
......@@ -98,7 +97,7 @@ class Mirror(Surface):
signal_gain=1e-9,
):
super().__init__(
name, R, T, L, phi, Rc, xbeta, ybeta, mass, signal_gain, MirrorConnections
name, R, T, L, phi, Rc, xbeta, ybeta, mass, signal_gain
)
self._add_port("p1", NodeType.OPTICAL)
......
......@@ -5,6 +5,7 @@ from finesse.simulations.base cimport frequency_info_t, ModelData, NodeBeamParam
from finesse.simulations cimport BaseSimulation
from finesse.element cimport BaseCValues
from finesse.components.workspace cimport ConnectorWorkspace, FillFuncWrapper
from finesse.components.modal.workspace cimport KnmConnectorWorkspace
from finesse.cyexpr cimport (
cy_expr,
......@@ -80,7 +81,7 @@ cdef class BeamsplitterValues(BaseCValues):
double alpha
cdef class BeamsplitterWorkspace(ConnectorWorkspace):
cdef class BeamsplitterWorkspace(KnmConnectorWorkspace):
cdef public:
# Complete scattering matrices for each propagation direction
KnmMatrix K12
......@@ -185,12 +186,12 @@ cdef class BeamsplitterWorkspace(ConnectorWorkspace):
cpdef compile_abcd_cy_exprs(self)
cpdef update_parameter_values(self)
cdef void initialise_knm_workspaces(BeamsplitterWorkspace ws) nogil
cdef void free_knm_workspaces(BeamsplitterWorkspace ws) nogil
cdef void flag_changing_knm_workspaces(BeamsplitterWorkspace ws)
cdef void update_changing_knm_workspaces(BeamsplitterWorkspace ws) nogil
cdef void compute_scattering_matrices(BeamsplitterWorkspace ws)
cdef object c_beamsplitter_fill(ConnectorWorkspace cws)
cdef void initialise_knm_workspaces(BeamsplitterWorkspace ws) nogil
cdef void free_knm_workspaces(BeamsplitterWorkspace ws) nogil
cdef void flag_changing_knm_workspaces(BeamsplitterWorkspace ws)
cdef void update_changing_knm_workspaces(BeamsplitterWorkspace ws) nogil
cdef void compute_scattering_matrices(BeamsplitterWorkspace ws)
......@@ -3,7 +3,7 @@ from finesse.knm cimport KnmMatrix, KnmWorkspace
from finesse.components.workspace cimport ConnectorWorkspace
from finesse.element cimport BaseCValues
from finesse.simulations.base cimport BaseSimulation
from finesse.components.modal.workspace cimport KnmConnectorWorkspace
from cpython.ref cimport PyObject
......@@ -29,7 +29,7 @@ cdef class IsolatorConnections:
isolator_connections conn_ptrs
cdef class IsolatorWorkspace(ConnectorWorkspace):
cdef class IsolatorWorkspace(KnmConnectorWorkspace):
cdef public:
# Complete scattering matrices for each propagation direction
KnmMatrix K12
......@@ -55,8 +55,8 @@ cdef class IsolatorWorkspace(ConnectorWorkspace):
KnmWorkspace K21_ws_y
cdef void initialise_knm_workspaces(IsolatorWorkspace ws) nogil
cdef void free_knm_workspaces(IsolatorWorkspace ws) nogil
cdef void flag_changing_knm_workspaces(IsolatorWorkspace ws)
cdef void update_changing_knm_workspaces(IsolatorWorkspace ws) nogil
cdef void compute_scattering_matrices(IsolatorWorkspace ws)
cdef void initialise_knm_workspaces(IsolatorWorkspace ws) nogil
cdef void free_knm_workspaces(IsolatorWorkspace ws) nogil
cdef void flag_changing_knm_workspaces(IsolatorWorkspace ws)
cdef void update_changing_knm_workspaces(IsolatorWorkspace ws) nogil
cdef void compute_scattering_matrices(IsolatorWorkspace ws)
......@@ -24,6 +24,7 @@ ctypedef (double*, ) ptr_tuple_1
LOGGER = logging.getLogger(__name__)
# TODO (sjr) make c_isolator_fill function?
cdef class IsolatorValues(BaseCValues):
def __init__(IsolatorValues self):
......@@ -41,7 +42,7 @@ cdef class IsolatorConnections:
self.conn_ptrs.P2i_P1o = <PyObject**>self.P2i_P1o.views
cdef class IsolatorWorkspace(ConnectorWorkspace):
cdef class IsolatorWorkspace(KnmConnectorWorkspace):
def __init__(self, owner, BaseSimulation sim, refill):
super().__init__(
owner,
......@@ -55,109 +56,107 @@ cdef class IsolatorWorkspace(ConnectorWorkspace):
self.P2i_id = sim.node_id(owner.p2.i)
self.P2o_id = sim.node_id(owner.p2.o)
# TODO (sjr) make c_isolator_fill function?
cdef void initialise_knm_workspaces(IsolatorWorkspace ws) nogil:
cdef:
NodeBeamParam q_p1i = ws.sim.trace[ws.P1i_id]
NodeBeamParam q_p1o = ws.sim.trace[ws.P1o_id]
NodeBeamParam q_p2i = ws.sim.trace[ws.P2i_id]
NodeBeamParam q_p2o = ws.sim.trace[ws.P2o_id]
cdef void initialise_knm_workspaces(IsolatorWorkspace ws) nogil:
cdef:
NodeBeamParam q_p1i = ws.sim.trace[ws.P1i_id]
NodeBeamParam q_p1o = ws.sim.trace[ws.P1o_id]
NodeBeamParam q_p2i = ws.sim.trace[ws.P2i_id]
NodeBeamParam q_p2o = ws.sim.trace[ws.P2o_id]
# Beam parameters for matched propagation of inputs
complex_t qx_p1o_matched_trns, qy_p1o_matched_trns
complex_t qx_p2o_matched_trns, qy_p2o_matched_trns
double lambda0 = ws.sim.model_data.lambda0
int maxtem = ws.sim.model_data.maxtem
# Transmission at port p1 -> p2
qx_p2o_matched_trns = q_p1i.qx
knm_ws_init(
&ws.K12_ws_x, qx_p2o_matched_trns, q_p2o.qx, 0, 0, ws.nr2, lambda0, maxtem,
)
qy_p2o_matched_trns = q_p1i.qy
knm_ws_init(
&ws.K12_ws_y, qy_p2o_matched_trns, q_p2o.qy, 0, 0, ws.nr2, lambda0, maxtem,
)
# Transmission at port p2 -> p1
qx_p1o_matched_trns = q_p2i.qx
knm_ws_init(
&ws.K21_ws_x, qx_p1o_matched_trns, q_p1o.qx, 0, 0, ws.nr1, lambda0, maxtem,
)
qy_p1o_matched_trns = q_p2i.qy
knm_ws_init(
&ws.K21_ws_y, qy_p1o_matched_trns, q_p1o.qy, 0, 0, ws.nr1, lambda0, maxtem,
)
cdef void free_knm_workspaces(IsolatorWorkspace ws) nogil:
knm_ws_free(&ws.K12_ws_x)
knm_ws_free(&ws.K12_ws_y)
knm_ws_free(&ws.K21_ws_x)
knm_ws_free(&ws.K21_ws_y)
cdef void flag_changing_knm_workspaces(IsolatorWorkspace ws):
cdef:
NodeBeamParam q_p1i = ws.sim.trace[ws.P1i_id]
NodeBeamParam q_p2i = ws.sim.trace[ws.P2i_id]
bint is_changing = q_p1i.is_changing or q_p2i.is_changing
# Transmission at port p1 -> p2
ws.K12_ws_x.is_mm_changing = is_changing
ws.K12_ws_y.is_mm_changing = is_changing
if knm_ws_is_changing(&ws.K12_ws_x) or knm_ws_is_changing(&ws.K12_ws_y):
LOGGER.info("%s.K12 is changing", ws.owner.name)
# Transmission at port p2 -> p1
ws.K21_ws_x.is_mm_changing = is_changing
ws.K21_ws_y.is_mm_changing = is_changing
if knm_ws_is_changing(&ws.K21_ws_x) or knm_ws_is_changing(&ws.K21_ws_y):
LOGGER.info("%s.K21 is changing", ws.owner.name)
cdef void update_changing_knm_workspaces(IsolatorWorkspace ws) nogil:
cdef:
NodeBeamParam q_p1i = ws.sim.trace[ws.P1i_id]
NodeBeamParam q_p1o = ws.sim.trace[ws.P1o_id]
NodeBeamParam q_p2i = ws.sim.trace[ws.P2i_id]
NodeBeamParam q_p2o = ws.sim.trace[ws.P2o_id]
complex_t qx_p1o_matched_trns, qy_p1o_matched_trns
complex_t qx_p2o_matched_trns, qy_p2o_matched_trns
if ws.K12_ws_x.is_mm_changing:
qx_p2o_matched_trns = q_p1i.qx
knm_ws_recompute_mismatch(&ws.K12_ws_x, qx_p2o_matched_trns, q_p2o.qx)
# Beam parameters for matched propagation of inputs
complex_t qx_p1o_matched_trns, qy_p1o_matched_trns
complex_t qx_p2o_matched_trns, qy_p2o_matched_trns
if ws.K12_ws_y.is_mm_changing:
double lambda0 = ws.sim.model_data.lambda0
int maxtem = ws.sim.model_data.maxtem
# Transmission at port p1 -> p2
qx_p2o_matched_trns = q_p1i.qx
knm_ws_init(
&ws.K12_ws_x, qx_p2o_matched_trns, q_p2o.qx, 0, 0, ws.nr2, lambda0, maxtem,
)
qy_p2o_matched_trns = q_p1i.qy
knm_ws_recompute_mismatch(&ws.K12_ws_y, qy_p2o_matched_trns, q_p2o.qy)
knm_ws_init(
&ws.K12_ws_y, qy_p2o_matched_trns, q_p2o.qy, 0, 0, ws.nr2, lambda0, maxtem,
)
if ws.K21_ws_x.is_mm_changing:
# Transmission at port p2 -> p1
qx_p1o_matched_trns = q_p2i.qx
knm_ws_recompute_mismatch(&ws.K21_ws_x, qx_p1o_matched_trns, q_p1o.qx)
if ws.K21_ws_y.is_mm_changing:
knm_ws_init(
&ws.K21_ws_x, qx_p1o_matched_trns, q_p1o.qx, 0, 0, ws.nr1, lambda0, maxtem,
)
qy_p1o_matched_trns = q_p2i.qy
knm_ws_recompute_mismatch(&ws.K21_ws_y, qy_p1o_matched_trns, q_p1o.qy)
knm_ws_init(
&ws.K21_ws_y, qy_p1o_matched_trns, q_p1o.qy, 0, 0, ws.nr1, lambda0, maxtem,
)
cdef void free_knm_workspaces(IsolatorWorkspace ws) nogil:
knm_ws_free(&ws.K12_ws_x)
knm_ws_free(&ws.K12_ws_y)
knm_ws_free(&ws.K21_ws_x)
knm_ws_free(&ws.K21_ws_y)
cdef void flag_changing_knm_workspaces(IsolatorWorkspace ws):
cdef:
NodeBeamParam q_p1i = ws.sim.trace[ws.P1i_id]
NodeBeamParam q_p2i = ws.sim.trace[ws.P2i_id]
bint is_changing = q_p1i.is_changing or q_p2i.is_changing
# Transmission at port p1 -> p2
ws.K12_ws_x.is_mm_changing = is_changing
ws.K12_ws_y.is_mm_changing = is_changing
if knm_ws_is_changing(&ws.K12_ws_x) or knm_ws_is_changing(&ws.K12_ws_y):
LOGGER.info("%s.K12 is changing", ws.owner.name)
# Transmission at port p2 -> p1
ws.K21_ws_x.is_mm_changing = is_changing
ws.K21_ws_y.is_mm_changing = is_changing
if knm_ws_is_changing(&ws.K21_ws_x) or knm_ws_is_changing(&ws.K21_ws_y):
LOGGER.info("%s.K21 is changing", ws.owner.name)
cdef void update_changing_knm_workspaces(IsolatorWorkspace ws) nogil:
cdef:
NodeBeamParam q_p1i = ws.sim.trace[ws.P1i_id]
NodeBeamParam q_p1o = ws.sim.trace[ws.P1o_id]
NodeBeamParam q_p2i = ws.sim.trace[ws.P2i_id]
NodeBeamParam q_p2o = ws.sim.trace[ws.P2o_id]
complex_t qx_p1o_matched_trns, qy_p1o_matched_trns
complex_t qx_p2o_matched_trns, qy_p2o_matched_trns
if ws.K12_ws_x.is_mm_changing:
qx_p2o_matched_trns = q_p1i.qx
knm_ws_recompute_mismatch(&ws.K12_ws_x, qx_p2o_matched_trns, q_p2o.qx)
if ws.K12_ws_y.is_mm_changing:
qy_p2o_matched_trns = q_p1i.qy
knm_ws_recompute_mismatch(&ws.K12_ws_y, qy_p2o_matched_trns, q_p2o.qy)
if ws.K21_ws_x.is_mm_changing:
qx_p1o_matched_trns = q_p2i.qx
knm_ws_recompute_mismatch(&ws.K21_ws_x, qx_p1o_matched_trns, q_p1o.qx)
if ws.K21_ws_y.is_mm_changing:
qy_p1o_matched_trns = q_p2i.qy
knm_ws_recompute_mismatch(&ws.K21_ws_y, qy_p1o_matched_trns, q_p1o.qy)
cdef void compute_scattering_matrices(IsolatorWorkspace ws):
# Transmission p1 -> p2
if knm_ws_is_changing(&ws.K12_ws_x) or knm_ws_is_changing(&ws.K12_ws_y):
compute_knm_matrix_bh(&ws.K12_ws_x, &ws.K12_ws_y, ws.sim.homs_view, ws.K12.data_view)
reverse_gouy_phases(ws.K12.data_view, ws.sim.homs_view, &ws.K12_ws_x, &ws.K12_ws_y, ws.K12.data_view)
cdef void compute_scattering_matrices(IsolatorWorkspace ws):
# Transmission p1 -> p2
if knm_ws_is_changing(&ws.K12_ws_x) or knm_ws_is_changing(&ws.K12_ws_y):
compute_knm_matrix_bh(&ws.K12_ws_x, &ws.K12_ws_y, ws.sim.homs_view, ws.K12.data_view)
reverse_gouy_phases(ws.K12.data_view, ws.sim.homs_view, &ws.K12_ws_x, &ws.K12_ws_y, ws.K12.data_view)
if ws.sim.model_data.zero_K00:
zero_tem00_phase(ws.K12.data_view, ws.K12.data_view)
if ws.sim.model_data.zero_K00:
zero_tem00_phase(ws.K12.data_view, ws.K12.data_view)
# Transmission p2 -> p1
if knm_ws_is_changing(&ws.K21_ws_x) or knm_ws_is_changing(&ws.K21_ws_y):
compute_knm_matrix_bh(&ws.K21_ws_x, &ws.K21_ws_y, ws.sim.homs_view, ws.K21.data_view)
reverse_gouy_phases(ws.K21.data_view, ws.sim.homs_view, &ws.K21_ws_x, &ws.K21_ws_y, ws.K21.data_view)
# Transmission p2 -> p1
if knm_ws_is_changing(&ws.K21_ws_x) or knm_ws_is_changing(&ws.K21_ws_y):
compute_knm_matrix_bh(&ws.K21_ws_x, &ws.K21_ws_y, ws.sim.homs_view, ws.K21.data_view)
reverse_gouy_phases(ws.K21.data_view, ws.sim.homs_view, &ws.K21_ws_x, &ws.K21_ws_y, ws.K21.data_view)
if ws.sim.model_data.zero_K00:
zero_tem00_phase(ws.K21.data_view, ws.K21.data_view)
if ws.sim.model_data.zero_K00:
zero_tem00_phase(ws.K21.data_view, ws.K21.data_view)
......@@ -5,6 +5,7 @@ from finesse.knm cimport KnmMatrix, KnmWorkspace
from finesse.components.workspace cimport ConnectorWorkspace
from finesse.element cimport BaseCValues
from finesse.simulations.base cimport BaseSimulation
from finesse.components.modal.workspace cimport KnmConnectorWorkspace
from finesse.cyexpr cimport (
cy_expr,
......@@ -38,7 +39,7 @@ cdef class LensConnections:
lens_connections conn_ptrs
cdef class LensWorkspace(ConnectorWorkspace):
cdef class LensWorkspace(KnmConnectorWorkspace):
cdef public:
# Complete scattering matrices for each propagation direction
KnmMatrix K12
......@@ -73,10 +74,8 @@ cdef class LensWorkspace(ConnectorWorkspace):
cpdef compile_abcd_cy_exprs(self)
cpdef update_parameter_values(self)
cdef void initialise_knm_workspaces(LensWorkspace ws) nogil
cdef void free_knm_workspaces(LensWorkspace ws) nogil
cdef void flag_changing_knm_workspaces(LensWorkspace ws)
cdef void update_changing_knm_workspaces(LensWorkspace ws) nogil
cdef void compute_scattering_matrices(LensWorkspace ws)
cdef void initialise_knm_workspaces(LensWorkspace ws) nogil
cdef void free_knm_workspaces(LensWorkspace ws) nogil
cdef void flag_changing_knm_workspaces(LensWorkspace ws)
cdef void update_changing_knm_workspaces(LensWorkspace ws) nogil
cdef void compute_scattering_matrices(LensWorkspace ws)
......@@ -45,7 +45,7 @@ cdef class LensConnections:
self.conn_ptrs.P2i_P1o = <PyObject**>self.P2i_P1o.views
cdef class LensWorkspace(ConnectorWorkspace):
cdef class LensWorkspace(KnmConnectorWorkspace):
def __init__(self, owner, BaseSimulation sim, refill):
super().__init__(
owner,
......@@ -103,110 +103,111 @@ cdef class LensWorkspace(ConnectorWorkspace):
if self.sym_abcd_Cy != NULL:
self.abcd_y[1][0] = cy_expr_eval(self.sym_abcd_Cy)
cdef void initialise_knm_workspaces(LensWorkspace ws) nogil:
cdef:
NodeBeamParam q_p1i = ws.sim.trace[ws.P1i_id]
NodeBeamParam q_p1o = ws.sim.trace[ws.P1o_id]
NodeBeamParam q_p2i = ws.sim.trace[ws.P2i_id]
NodeBeamParam q_p2o = ws.sim.trace[ws.P2o_id]
# TODO (sjr) make c_lens_fill function?
# Beam parameters for matched propagation of inputs
complex_t qx_p1o_matched_trns, qy_p1o_matched_trns
complex_t qx_p2o_matched_trns, qy_p2o_matched_trns
cdef void initialise_knm_workspaces(LensWorkspace ws) nogil:
cdef:
NodeBeamParam q_p1i = ws.sim.trace[ws.P1i_id]
NodeBeamParam q_p1o = ws.sim.trace[ws.P1o_id]
NodeBeamParam q_p2i = ws.sim.trace[ws.P2i_id]
NodeBeamParam q_p2o = ws.sim.trace[ws.P2o_id]
# Beam parameters for matched propagation of inputs
complex_t qx_p1o_matched_trns, qy_p1o_matched_trns
complex_t qx_p2o_matched_trns, qy_p2o_matched_trns
double lambda0 = ws.sim.model_data.lambda0
int maxtem = ws.sim.model_data.maxtem
# Transmission at port p1 -> p2
qx_p2o_matched_trns = transform_q(ws.abcd_x, q_p1i.qx, ws.nr1, ws.nr2)
knm_ws_init(
&ws.K12_ws_x, qx_p2o_matched_trns, q_p2o.qx, 0, 0, ws.nr2, lambda0, maxtem,
)
qy_p2o_matched_trns = transform_q(ws.abcd_y, q_p1i.qy, ws.nr1, ws.nr2)
knm_ws_init(
&ws.K12_ws_y, qy_p2o_matched_trns, q_p2o.qy, 0, 0, ws.nr2, lambda0, maxtem,
)
# Transmission at port p2 -> p1
qx_p1o_matched_trns = transform_q(ws.abcd_x, q_p2i.qx, ws.nr2, ws.nr1)
knm_ws_init(
&ws.K21_ws_x, qx_p1o_matched_trns, q_p1o.qx, 0, 0, ws.nr1, lambda0, maxtem,
)
qy_p1o_matched_trns = transform_q(ws.abcd_y, q_p2i.qy, ws.nr2, ws.nr1)
knm_ws_init(
&ws.K21_ws_y, qy_p1o_matched_trns, q_p1o.qy, 0, 0, ws.nr1, lambda0, maxtem,
)
cdef void free_knm_workspaces(LensWorkspace ws) nogil:
knm_ws_free(&ws.K12_ws_x)
knm_ws_free(&ws.K12_ws_y)
knm_ws_free(&ws.K21_ws_x)
knm_ws_free(&ws.K21_ws_y)
cdef void flag_changing_knm_workspaces(LensWorkspace ws):
cdef:
NodeBeamParam q_p1i = ws.sim.trace[ws.P1i_id]
NodeBeamParam q_p2i = ws.sim.trace[ws.P2i_id]
bint is_changing = q_p1i.is_changing or q_p2i.is_changing
# Transmission at port p1 -> p2
ws.K12_ws_x.is_mm_changing = is_changing
ws.K12_ws_y.is_mm_changing = is_changing
if knm_ws_is_changing(&ws.K12_ws_x) or knm_ws_is_changing(&ws.K12_ws_y):
LOGGER.info("%s.K12 is changing", ws.owner.name)
# Transmission at port p2 -> p1
ws.K21_ws_x.is_mm_changing = is_changing
ws.K21_ws_y.is_mm_changing = is_changing
if knm_ws_is_changing(&ws.K21_ws_x) or knm_ws_is_changing(&ws.K21_ws_y):
LOGGER.info("%s.K21 is changing", ws.owner.name)
cdef void update_changing_knm_workspaces(LensWorkspace ws) nogil:
cdef:
NodeBeamParam q_p1i = ws.sim.trace[ws.P1i_id]
NodeBeamParam q_p1o = ws.sim.trace[ws.P1o_id]
NodeBeamParam q_p2i = ws.sim.trace[ws.P2i_id]
NodeBeamParam q_p2o = ws.sim.trace[ws.P2o_id]
complex_t qx_p1o_matched_trns, qy_p1o_matched_trns
complex_t qx_p2o_matched_trns, qy_p2o_matched_trns
if ws.K12_ws_x.is_mm_changing:
qx_p2o_matched_trns = transform_q(ws.abcd_x, q_p1i.qx, ws.nr1, ws.nr2)
knm_ws_recompute_mismatch(&ws.K12_ws_x, qx_p2o_matched_trns, q_p2o.qx)
double lambda0 = ws.sim.model_data.lambda0
int maxtem = ws.sim.model_data.maxtem
if ws.K12_ws_y.is_mm_changing:
# Transmission at port p1 -> p2
qx_p2o_matched_trns = transform_q(ws.abcd_x, q_p1i.qx, ws.nr1, ws.nr2)
knm_ws_init(
&ws.K12_ws_x, qx_p2o_matched_trns, q_p2o.qx, 0, 0, ws.nr2, lambda0, maxtem,
)
qy_p2o_matched_trns = transform_q(ws.abcd_y, q_p1i.qy, ws.nr1, ws.nr2)
knm_ws_recompute_mismatch(&ws.K12_ws_y, qy_p2o_matched_trns, q_p2o.qy)
knm_ws_init(
&ws.K12_ws_y, qy_p2o_matched_trns, q_p2o.qy, 0, 0, ws.nr2, lambda0, maxtem,
)
if ws.K21_ws_x.is_mm_changing:
# Transmission at port p2 -> p1
qx_p1o_matched_trns = transform_q(ws.abcd_x, q_p2i.qx, ws.nr2, ws.nr1)
knm_ws_recompute_mismatch(&ws.K21_ws_x, qx_p1o_matched_trns, q_p1o.qx)
if ws.K21_ws_y.is_mm_changing:
knm_ws_init(
&ws.K21_ws_x, qx_p1o_matched_trns, q_p1o.qx, 0, 0, ws.nr1, lambda0, maxtem,
)
qy_p1o_matched_trns = transform_q(ws.abcd_y, q_p2i.qy, ws.nr2, ws.nr1)
knm_ws_recompute_mismatch(&ws.K21_ws_y, qy_p1o_matched_trns, q_p1o.qy)
knm_ws_init(
&ws.K21_ws_y, qy_p1o_matched_trns, q_p1o.qy, 0, 0, ws.nr1, lambda0, maxtem,
)
cdef void free_knm_workspaces(LensWorkspace ws) nogil: