finesse.simulations package

Subpackages

Submodules

finesse.simulations.base module

class finesse.simulations.base.ModelSettings

Bases: object

A class used to represent the settings of a model.

Attributes

phase_configPhaseConfig

The configuration of the phase.

homs_viewndarray

A view on the higher order modes (HOMs).

max_nint

The maximum n value in the HOMs.

max_mint

The maximum m value in the HOMs.

num_HOMsint

The number of HOMs.

lambda0float

The wavelength.

f0float

The frequency, calculated as the speed of light divided by the wavelength.

k0float

The wave number, calculated as 2*pi divided by the wavelength.

Methods

__reduce__()

Returns a tuple that can be used to rebuild the object using rebuild_model_settings.

set_lambda0(value)

Sets the wavelength and updates the frequency and wave number accordingly.

EPSILON0_C

EPSILON0_C: ‘double’

UNIT_VACUUM

UNIT_VACUUM: ‘double’

f0

f0: ‘double’

fsig

fsig: ‘double’

homs

Returns a view on the higher order modes (HOMs).

Returns

ndarray

A view on the HOMs.

homs_view

homs_view: ‘int[:, ::1]’

is_modal

is_modal: ‘bool’

k0

k0: ‘double’

lambda0

lambda0: ‘double’

max_m

max_m: ‘int’

max_n

max_n: ‘int’

num_HOMs

num_HOMs: ‘int’

phase_config

phase_config: finesse.simulations.base.PhaseConfig

set_lambda0(self, value)

Sets the wavelength and updates the frequency and wave number accordingly.

Parameters

valuefloat

The new wavelength.

x_scale

x_scale: ‘double’

class finesse.simulations.base.PhaseConfig

Bases: object

v2_transmission_phase

v2_transmission_phase: ‘bool’

zero_k00

zero_k00: ‘bool’

zero_tem00_gouy

zero_tem00_gouy: ‘bool’

finesse.simulations.base.rebuild_model_settings(d)

Rebuilds the model settings from a dictionary.

Parameters

ddict

A dictionary where each key-value pair represents a setting name and its value.

Returns

ModelSettings

A new ModelSettings object with its attributes set according to d.

finesse.simulations.basesolver module

class finesse.simulations.basesolver.BaseSolver(str name, list nodes, FrequencyContainer optical_frequencies, dict signal_frequencies, bool is_signal_matrix, bool forced_refill, dict node_aliases, bool debug_mode=False)

Bases: object

A linear set of systems can be represented as a matrix, each equation in this system is a particular state which we want to compute. The system is solved by applying some inputs into various states, or the right hand side (RHS) vector, and solving the system.

The underlying matrix can be either a sparse or dense matrix. This class should not assume either, but merely call upon a standard matrix interface. Therefore the algorithm used for solving can vary significantly. The overall matrix is sectioned into submatricies which connect various states together.

Nodes represent a physical location in the model in which some state of the system must be computed. Some nodes can have multiple states, such as multiple optical modes.

add_rhs(self, str key)
any_frequencies_changing
assign_noise_operators(self, connector_workspaces)
assign_operators(self, connector_workspaces)

An important function. This takes all the connector workspaces - i.e. model elements that have requested some type of connection in the model - and ensures they have the correct submatrix allocated to them in for this solver.

changing_mismatch_node_ids
clear_rhs(self)
connections
construct(self)

This is called when workspaces and submatrices have been setup. Calling construct should now go and allocate the memory for the matrix and RHS.

This method should be overwritten by an inheriting solver class with specfics of the solving technique.

destruct(self)

This is called when finishing and unbuilding the simulation.

Classes that override this call should mindful of what this method is doing to and call it.

factor(self)
fill_noise_inputs(self)
fill_rhs(self)
findex(self, node, Py_ssize_t freq) Py_ssize_t

Returns simulation unique index for a given frequency at this node. Used to refer to submatrices of HOMs in the interferometer matrix.

Parameters

nodeNode

Node object to get the index of.

freqint

Frequency index.

Returns

indexint

Index of the node for a given frequency.

forced_refill
get_frequency_object(self, frequency, node)

Get a Frequency object corresponding to a numerical or symbolic value. Returns none if nothing has been found.

Parameters

fnumber or Symbol

Frequency to search for in this simulation.

Returns

Frequency

The frequency object.

get_node_frequencies(self, node) tuple
get_node_info(self, node)

For a given node (object or name) the key parameters for where this node is represented in the matrix of linear equations.

Parameters

node[str | Node]

The name or the Node object of the node.

Returns

dict: A dictionary containing the following information about the node:
  • index: The index of the node.

  • rhs_index: The index of the right-hand side vector associated with the node.

  • freq_index: The index of the frequency vector associated with the node.

  • nfreqs: The number of frequencies.

  • nhoms: The number of higher order modes. [TODO generalise to pixels/HOMs/whatever]

index_2_node
initial_fill(self)
initial_run(self)

Once a solver has been constructed it will most likely need to be initially filled and ran. Some sparse solvers for example must do a full factor first, then can perform faster refactors.

This method should be overwritten by an inheriting solver class with specfics of the solving technique.

initialise(self, sim)
input_components(self)

Components that are injecting something into the simulation

manual_rhs

manual_rhs: ‘bool’

node_2_index
node_aliases
node_id(self, node) Py_ssize_t
nodes
noise_sources
num_solves
optical_frequencies
print_matrix(self)
refactor(self)
refill(self)
refill_rhs(self)
run(self)

Executes the simulation for model in its current state.

Takes the following steps to compute an output:
  • If self.manual_rhs:
    • Clears the RHS vector

    • Fills the RHS vector

  • Fills the matrix

  • Solves

setup_nodes(self, list all_nodes, dict node_aliases)
signal_frequencies
solve(self)
solve_noises(self)
unique_elec_mech_fcnts
update_frequency_info(self)
workspaces
class finesse.simulations.basesolver.MatrixSystemWorkspaces

Bases: object

clear_workspaces(self)
detector_list_to_C(self)
list_to_C(self)

Converts the python lists of workspaces into C Pyobject arrays for fast loop access.

noise_detectors
num_noise_detectors
num_to_noise_input_refill
num_to_noise_refill
num_to_refill
num_to_rhs_refill
to_initial_fill
to_noise_input_refill
to_noise_refill
to_refill
to_rhs_refill

finesse.simulations.debug module

finesse.simulations.homsolver module

class finesse.simulations.homsolver.HOMSolver(str name, list nodes, FrequencyContainer optical_frequencies, dict signal_frequencies, bool is_signal_matrix, bool forced_refill, dict node_aliases, int num_optical_homs, bool debug_mode=False)

Bases: BaseSolver

This is class provides an interface for generic simulations that are solving for a vector of higher order modes at each node. This allows detectors and other calculation code to be able to perform the same calculations without being specified. This class should be inherited to provide specific implementations. Considerations are:

  • HOM vector at each node should be contiguous in memory

  • Not all nodes will have a HOM vector if it isn’t being solved for

  • Signal nodes will have a single “HOM”

add_noise_matrix(self, key)
component_edge_fill(self, comp, edgestr, f1, f2, conjugate=False)

Returns a matrix for the submatrix an element has requested for different connections it needs. The key is:

(element, connection_name, ifreq, ofreq)

This is a context manager, to be used like with sim.component_edge_fill(key) as mat:

mat[:] = computations

Parameters

elementfinesse.component.Connector

The object reference that created the requests.

connection_namestr

String name given to the connection.

ifreqfinesse.Frequency

Incoming frequency.

ofreqfinesse.Frequency

Outgoing frequency.

Returns

matrix

component_edge_fill3(self, owner_idx, conn_idx, f1_index, f2_index)
construct(self)
field(self, node, Py_ssize_t freq=0, Py_ssize_t hom=0) Py_ssize_t

Returns simulation unique index of a field at a particular frequency index at this node.

Parameters

nodeNode

Node object to get the index of.

freqint

Frequency index.

homint, optional

Higher Order Mode index, defaults to zero.

findex(self, node, Py_ssize_t freq) Py_ssize_t
get_node_info(self, node)

For a given node (object or name) the key parameters for where this node is represented in the matrix of linear equations.

Parameters

node[str | Node]

The name or the Node object of the node.

Returns

dict: A dictionary containing the following information about the node:
  • index: The index of the node.

  • rhs_index: The index of the right-hand side vector associated with the node.

  • freq_index: The index of the frequency vector associated with the node.

  • nfreqs: The number of frequencies.

  • nhoms: The number of higher order modes. [TODO generalise to pixels/HOMs/whatever]

get_out(self, node, Py_ssize_t freq=0, Py_ssize_t hom=0) double complex
nhoms
node_field_vector

Returns the higher order mode field vector of a given node at a specific frequency index.

Parameters

node[int|object|str]

The node for which to retrieve the field vector. This can be a string full-name of a node, ‘m1.p1.i’, or a node object. It can also be an integer index of the node for this simulation.

freq_idxunsigned long

The index of the frequency at which to retrieve the field vector.

Returns

np.ndarray:

A copy of the field vector of the node at the specified frequency index.

out_view

out_view: ‘double complex[::1]’

out_view_size

out_view_size: ‘Py_ssize_t’

set_source(self, node, int freq_idx, int hom_idx, double complex value)
setup_nodes(self, list all_nodes, dict node_aliases)

finesse.simulations.simulation module

class finesse.simulations.simulation.BaseSimulation(model, str name, dict simulation_options)

Bases: object

This base level class should be inherited by others to perform the exact needs of a particular type of simulation. This BaseSimulation class contains the methods to store common settings as well as functionality for beam tracing through a model, and detecting which beam parameters will be changing. Developers should ensure that methods raising NotImplementedError are defined in any deriving classes.

build(self)
build_carrier_solver(self, nodes, optical_frequencies)
build_signal_solver(self, nodes, optical_frequencies, signal_frequencies)
carrier
carrier_frequencies_to_use
cavity_workspaces

cavity_workspaces: dict

changing_mismatch_couplings
changing_mismatch_edges
changing_parameters
compute_signals
detector_workspaces
generate_carrier_frequencies(self)

Returns a list of Frequency objects that the model has requested

generate_signal_frequencies(self, nodes, FrequencyContainer carrier_optical_frequencies)

Generates the optical, mechanical, and electrical frequencies that should be modelled by the signal simulation.

get_q(self, node)

Returns a tuple of (qx, qy) for a given node. The returned value is only valid until this simulations trace forest has been updated.

Parameters

nodefinesse.components.OpticalNode

Node to get beam parameters at

Returns

(qx, qy)

Tuple of x and y beam parameters

gouy_phase_workspaces
initial_trace_sol
is_component_in_mismatch_couplings(self, comp)

Determines whether the connector comp is associated with any of the node couplings in the stored changing mismatch couplings.

Note

This method can be replaced if connectors eventually use more granular refill flags — i.e. per coupling refill flags. Then the check for refilling that coupling can simply include the condition (from_node, to_node) in sim.changing_mismatch_couplings.

is_modal
modal_update(self)

Updates HOM related dependencies / properties of the model.

These updates are as follows:

  • Execute a beam trace on the changing trace trees

  • Computes the changing scattering matrices

  • Calculates the Gouy phase of Spaces and Laser power coefficients

Returns

validitybool

True if the modal update was successful, or False if an unstable cavity combination prevented a beam trace from being performed.

model
model_settings
name
nodes_with_changing_q
optical_nodes_to_use
post_build(self)

Post build calls functions that should be called after everything else has been built. For example, detectors that might rely on components being set up.

pre_build(self)

Pre-build performs some common setup routine that should be applicable to any deriving simulation class. This method performs the following tasks:

  • Checks if the signal frequency (fsig) is changing and if its value is None. If so, it sets a default value of 1 Hz.

  • Creates a list of all the changing parameters in the simulation.

  • Creates a set of tunable parameters from the changing parameters.

  • Determines if signal computation is required based on the value of fsig.f. Sets self.compute_signals

  • Determines if the simulation is modal or not. Sets self.is_modal

  • Initializes the model settings

  • Initializes the simulation configuration data.

  • Generates carrier frequencies based on the model.

  • Initializes the trace forest if the simulation is modal.

  • Determines the changing beam parameters if the simulation is modal.

readout_workspaces
run_carrier(self)

Runs the carrier matrix solver for the current state of the model. This will update all the C based structs with the current model state so that filling and calculations can be performed.

Returns

validitybool

True if this was a valid run, or False if a recoverable error occurred which results in the output being invalid for this call.

run_signal(self, solve_noises=True)

Runs the signal matrix solver for the current state. This function should assume that a call to the run_carrier method has preceeded it. Many modal and parameter updates should happen in there already, so do not need to be repeated here.

setup_build(self)
setup_output_workspaces(self)
signal
signal_frequencies_to_use
signal_nodes_to_use
signal_optical_frequencies_to_use
simulation_options
trace_beam(self)

Traces the beam through the paths which are dependent upon changing geometric parameter(s).

This method will modify those entries in the self.trace C array which were previously determined to have changing beam parameter values.

Returns

validitybool

True if the tracing was successful, or False if an unstable cavity combination prevented a beam trace from being performed.

Raises

exBeamTraceException

If the "unstable_handling" entry of the associated Model.sim_trace_config dict is "abort" and any unstable cavities were encountered.

trace_forest
trace_node_index
tunable_parameters
unbuild(self)
update_all_parameter_values(self)

Loops through all workspaces to update the C structs so they represent the current model element parameter values.

update_cavities(self)
update_map_data(self)

This will cycle through each map being used and if it is defined by a function it will be evaluated again.

variable_workspaces

variable_workspaces: list

workspace_name_map

workspace_name_map: dict

workspaces

workspaces: list

finesse.simulations.workspace module

class finesse.simulations.workspace.ABCDWorkspace(BaseSimulation sim, owner, values=None)

Bases: ElementWorkspace

This class represents a workspace for ABCD matrix calculations in Finesse simulations. It inherits from the ElementWorkspace class.

Attributes

simBaseSimulation

The BaseSimulation object associated with the workspace.

ownerobject

The owner object of the workspace.

valuesobject, optional

Additional values associated with the workspace.

Methods

set_gouy_function(callback)

Sets the callback function for computing the gouy phase terms.

compile_abcd_cy_exprs()

Compiles the ABCD matrix expressions for the workspace.

flag_changing_beam_parameters(changing_edges)

Called when the workspace should check if changing beam parameters will affect this workspace’s calculations.

update_map_data()

Called when the workspace should update any map data

compile_abcd_cy_exprs(self)

Compiles the ABCD matrix expressions for the workspace. It is called during the simulation setup phase.

flag_changing_beam_parameters(self, OrderedSet changing_edges)

Flags changing beam parameters for the workspace. Workspaces that inherit from this must then check the edges it is dealing with and determine whether it needs to do extra calculations or not.

Parameters

changing_edgesset

A set of edges (tuple of (in, out) node indices) that have a changing beam parameter. The index can be related back to a node object by checking the BaseSimulation.trace_node_index dictionary.

fn_gouy_c
fn_gouy_py
set_gouy_function(self, callback)

Sets the callback function that will be used by the model to compute the gouy phase terms for an element. This can either be a Python function or cdef wrapped with GouyFuncWrapper.

Parameters

callbackfunction or GouyFuncWrapper

The callback function that computes the gouy phase terms for an element. It can be either a Python function or a cdef wrapped function.

update_map_data(self)

Signals that a workspace should update any data held in maps it is using. This is called when the simulation is first run and when the UpdateMaps action is called.

class finesse.simulations.workspace.GouyFuncWrapper

Bases: object

Helper class for wrapping a C fill function that can be referenced from Python by objects. This allows a direct C call to the function from other cdef functions.

Wraps a cdef for setting the gouy phase during a modal simulation.

Examples

Create a C function then wrap it using this class:

>>> cdef int c_set_gouy(ABCDWorkspace ptr_ws) noexcept:
>>>    cdef MirrorWorkspace ws = <MirrorWorkspace>ptr_ws
>>>    ...
>>>
>>> fill = GouyFuncWrapper.make_from_ptr(c_set_gouy)

Module contents

Holds the various instances of simulation classes.

Listed below are all the sub-modules of the simulations module with a brief description of the contents of each.

class finesse.simulations.BaseSimulation(model, str name, dict simulation_options)

Bases: object

This base level class should be inherited by others to perform the exact needs of a particular type of simulation. This BaseSimulation class contains the methods to store common settings as well as functionality for beam tracing through a model, and detecting which beam parameters will be changing. Developers should ensure that methods raising NotImplementedError are defined in any deriving classes.

build(self)
build_carrier_solver(self, nodes, optical_frequencies)
build_signal_solver(self, nodes, optical_frequencies, signal_frequencies)
carrier
carrier_frequencies_to_use
cavity_workspaces

cavity_workspaces: dict

changing_mismatch_couplings
changing_mismatch_edges
changing_parameters
compute_signals
detector_workspaces
generate_carrier_frequencies(self)

Returns a list of Frequency objects that the model has requested

generate_signal_frequencies(self, nodes, FrequencyContainer carrier_optical_frequencies)

Generates the optical, mechanical, and electrical frequencies that should be modelled by the signal simulation.

get_q(self, node)

Returns a tuple of (qx, qy) for a given node. The returned value is only valid until this simulations trace forest has been updated.

Parameters

nodefinesse.components.OpticalNode

Node to get beam parameters at

Returns

(qx, qy)

Tuple of x and y beam parameters

gouy_phase_workspaces
initial_trace_sol
is_component_in_mismatch_couplings(self, comp)

Determines whether the connector comp is associated with any of the node couplings in the stored changing mismatch couplings.

Note

This method can be replaced if connectors eventually use more granular refill flags — i.e. per coupling refill flags. Then the check for refilling that coupling can simply include the condition (from_node, to_node) in sim.changing_mismatch_couplings.

is_modal
modal_update(self)

Updates HOM related dependencies / properties of the model.

These updates are as follows:

  • Execute a beam trace on the changing trace trees

  • Computes the changing scattering matrices

  • Calculates the Gouy phase of Spaces and Laser power coefficients

Returns

validitybool

True if the modal update was successful, or False if an unstable cavity combination prevented a beam trace from being performed.

model
model_settings
name
nodes_with_changing_q
optical_nodes_to_use
post_build(self)

Post build calls functions that should be called after everything else has been built. For example, detectors that might rely on components being set up.

pre_build(self)

Pre-build performs some common setup routine that should be applicable to any deriving simulation class. This method performs the following tasks:

  • Checks if the signal frequency (fsig) is changing and if its value is None. If so, it sets a default value of 1 Hz.

  • Creates a list of all the changing parameters in the simulation.

  • Creates a set of tunable parameters from the changing parameters.

  • Determines if signal computation is required based on the value of fsig.f. Sets self.compute_signals

  • Determines if the simulation is modal or not. Sets self.is_modal

  • Initializes the model settings

  • Initializes the simulation configuration data.

  • Generates carrier frequencies based on the model.

  • Initializes the trace forest if the simulation is modal.

  • Determines the changing beam parameters if the simulation is modal.

readout_workspaces
run_carrier(self)

Runs the carrier matrix solver for the current state of the model. This will update all the C based structs with the current model state so that filling and calculations can be performed.

Returns

validitybool

True if this was a valid run, or False if a recoverable error occurred which results in the output being invalid for this call.

run_signal(self, solve_noises=True)

Runs the signal matrix solver for the current state. This function should assume that a call to the run_carrier method has preceeded it. Many modal and parameter updates should happen in there already, so do not need to be repeated here.

setup_build(self)
setup_output_workspaces(self)
signal
signal_frequencies_to_use
signal_nodes_to_use
signal_optical_frequencies_to_use
simulation_options
trace_beam(self)

Traces the beam through the paths which are dependent upon changing geometric parameter(s).

This method will modify those entries in the self.trace C array which were previously determined to have changing beam parameter values.

Returns

validitybool

True if the tracing was successful, or False if an unstable cavity combination prevented a beam trace from being performed.

Raises

exBeamTraceException

If the "unstable_handling" entry of the associated Model.sim_trace_config dict is "abort" and any unstable cavities were encountered.

trace_forest
trace_node_index
tunable_parameters
unbuild(self)
update_all_parameter_values(self)

Loops through all workspaces to update the C structs so they represent the current model element parameter values.

update_cavities(self)
update_map_data(self)

This will cycle through each map being used and if it is defined by a function it will be evaluated again.

variable_workspaces

variable_workspaces: list

workspace_name_map

workspace_name_map: dict

workspaces

workspaces: list

class finesse.simulations.BaseSolver(str name, list nodes, FrequencyContainer optical_frequencies, dict signal_frequencies, bool is_signal_matrix, bool forced_refill, dict node_aliases, bool debug_mode=False)

Bases: object

A linear set of systems can be represented as a matrix, each equation in this system is a particular state which we want to compute. The system is solved by applying some inputs into various states, or the right hand side (RHS) vector, and solving the system.

The underlying matrix can be either a sparse or dense matrix. This class should not assume either, but merely call upon a standard matrix interface. Therefore the algorithm used for solving can vary significantly. The overall matrix is sectioned into submatricies which connect various states together.

Nodes represent a physical location in the model in which some state of the system must be computed. Some nodes can have multiple states, such as multiple optical modes.

add_rhs(self, str key)
any_frequencies_changing
assign_noise_operators(self, connector_workspaces)
assign_operators(self, connector_workspaces)

An important function. This takes all the connector workspaces - i.e. model elements that have requested some type of connection in the model - and ensures they have the correct submatrix allocated to them in for this solver.

changing_mismatch_node_ids
clear_rhs(self)
connections
construct(self)

This is called when workspaces and submatrices have been setup. Calling construct should now go and allocate the memory for the matrix and RHS.

This method should be overwritten by an inheriting solver class with specfics of the solving technique.

destruct(self)

This is called when finishing and unbuilding the simulation.

Classes that override this call should mindful of what this method is doing to and call it.

factor(self)
fill_noise_inputs(self)
fill_rhs(self)
findex(self, node, Py_ssize_t freq) Py_ssize_t

Returns simulation unique index for a given frequency at this node. Used to refer to submatrices of HOMs in the interferometer matrix.

Parameters

nodeNode

Node object to get the index of.

freqint

Frequency index.

Returns

indexint

Index of the node for a given frequency.

forced_refill
get_frequency_object(self, frequency, node)

Get a Frequency object corresponding to a numerical or symbolic value. Returns none if nothing has been found.

Parameters

fnumber or Symbol

Frequency to search for in this simulation.

Returns

Frequency

The frequency object.

get_node_frequencies(self, node) tuple
get_node_info(self, node)

For a given node (object or name) the key parameters for where this node is represented in the matrix of linear equations.

Parameters

node[str | Node]

The name or the Node object of the node.

Returns

dict: A dictionary containing the following information about the node:
  • index: The index of the node.

  • rhs_index: The index of the right-hand side vector associated with the node.

  • freq_index: The index of the frequency vector associated with the node.

  • nfreqs: The number of frequencies.

  • nhoms: The number of higher order modes. [TODO generalise to pixels/HOMs/whatever]

index_2_node
initial_fill(self)
initial_run(self)

Once a solver has been constructed it will most likely need to be initially filled and ran. Some sparse solvers for example must do a full factor first, then can perform faster refactors.

This method should be overwritten by an inheriting solver class with specfics of the solving technique.

initialise(self, sim)
input_components(self)

Components that are injecting something into the simulation

manual_rhs

manual_rhs: ‘bool’

node_2_index
node_aliases
node_id(self, node) Py_ssize_t
nodes
noise_sources
num_solves
optical_frequencies
print_matrix(self)
refactor(self)
refill(self)
refill_rhs(self)
run(self)

Executes the simulation for model in its current state.

Takes the following steps to compute an output:
  • If self.manual_rhs:
    • Clears the RHS vector

    • Fills the RHS vector

  • Fills the matrix

  • Solves

setup_nodes(self, list all_nodes, dict node_aliases)
signal_frequencies
solve(self)
solve_noises(self)
unique_elec_mech_fcnts
update_frequency_info(self)
workspaces