Merging carrier and signal simulation
A large amount of changes here, hopefully for the better:
BaseSimulation is gone. CarrierSignalMatrixSimulation replaces it effectively. This new class embodies the simulation methodology of Finesse, solving two sparse matrices, can be plane-wave or modal.
CarrierSignalMatrixSimulation has two matrix solvers, one for the carrier and one for the signal.
sim.signal. These hold all the information regards node indicies, views of the RHS output, solving, filling, workspaces, etc.
Detector workspaces are now stored in the single
CarrierSignalMatrixSimulation object as it should be, rather than in the model.
CarrierSignalMatrixSimulation contains common workspaces and beam tracing between the two matrix solvers. No need for all the annoying duplicated code and weird work arounds.
Matrix filling methods are now split, you specify one for carrier and one for signal. Looks like this now:
ws = MirrorWorkspace(self, sim, refill) ws.carrier.set_fill_function(mirror_carrier_fill) ws.signal.set_fill_function(mirror_signal_fill)
This change means nearly every file needed updating slightly.
Getting some output now looks like, weird
DC in the name gone:
ws.sim.carrier.get_out(self.p1.i, f1.index, k)
ws.carrier is a
ConnectorMatrixSimulationInfo which contains details on the matrix specific connections indices for accessing fill functions, and points to fill functions.
ws.sim.carrier is a reference to the
MatrixSystemSolver for actually doing filling, solving. KLU class inherits from this solver class to do its job. Dense matrix solver and Lee's code unfortunately do not work
sim.frequencies has been renamed to
sim.optical_frequencies which is a
Optical and signal connections objects now have to be both stored at once. Given all the purely optical filling is identical between carrier and signal, fill methods should be abstracted enough to be used between them:
cdef class MirrorOpticalConnections: cdef public: int P1i_P1o_idx int P2i_P2o_idx int P1i_P2o_idx int P2i_P1o_idx cdef readonly: SubCCSView1DArray P1i_P1o SubCCSView1DArray P2i_P2o SubCCSView1DArray P1i_P2o SubCCSView1DArray P2i_P1o cdef: mirror_optical_connections opt_conn_ptrs cdef class MirrorSignalConnections(MirrorOpticalConnections): cdef public: int P1i_Fz_idx, P2i_Fz_idx, P1o_Fz_idx, P2o_Fz_idx int Z_P1o_idx, Z_P2o_idx cdef readonly: SubCCSView2DArray P1i_Fz SubCCSView2DArray P1o_Fz SubCCSView2DArray P2i_Fz SubCCSView2DArray P2o_Fz SubCCSView2DArray Z_P1o SubCCSView2DArray Z_P2o cdef: mirror_signal_connections sig_conn_ptrs
These new abstract fill methods can look something like this:
cdef inline void mirror_fill_optical_2_optical( mirror_optical_connections *conn, MirrorWorkspace ws, frequency_info_t *freq, double r, complex_t it, double phi ): cdef double phase_shift = 2.0 * phi * (1 + freq.f / ws.sim.model_data.f0) cdef complex_t tuning = cexp(1.0j * phase_shift) cdef complex_t ctuning = conj(tuning) # Reflections (<SubCCSView>conn.P1i_P1o[freq.index]).fill_za_zm_2( r * tuning, ws.K11.ptr, ws.K11.stride1, ws.K11.stride2 ) (<SubCCSView>conn.P2i_P2o[freq.index]).fill_za_zm_2( r * ctuning, ws.K22.ptr, ws.K22.stride1, ws.K22.stride2 ) # Transmission (<SubCCSView>conn.P1i_P2o[freq.index]).fill_za_zm_2( it, ws.K12.ptr, ws.K12.stride1, ws.K12.stride2 ) (<SubCCSView>conn.P2i_P1o[freq.index]).fill_za_zm_2( it, ws.K21.ptr, ws.K21.stride1, ws.K21.stride2 )