예제 #1
0
    def connect_circuit(netlist):
        """
        Connects the s-matrices of a photonic circuit given its Netlist
        and returns a single 'SimulatedComponent' object containing the frequency
        array, the assembled s-matrix, and a list of the external nets (negative 
        integers).

        Parameters
        ----------
        component_list : List[SimulatedComponent]
            A list of the components to be connected.
        net_count : int
            The total number of internal nets in the component list.

        Returns
        -------
        combined : ScatteringMatrix
            After the circuit has been fully connected, the result is a single 
            ComponentSimulation with fields f (frequency), s (s-matrix), and nets 
            (external ports: negative numbers, as strings).

        Notes
        -----
        This function doesn't actually store ``combined`` on each iteration 
        through the netlist. That's because the Pin objects can only reference
        one PinList at a time, which in turn can only reference one Element.
        Since we transferring the actual Pin objects between lists, keeping
        a reference to the Pin also keeps a reference to the ``combined`` 
        Element alive. Hence, we track pins but not the ``SimulationResult``.
        """
        _logger = _module_logger.getChild('SweepSimulation.connect_circuit')

        # FIXME: What if there are no items in the netlist (only one element
        # in the circuit)?
        for net in netlist:
            p1, p2 = net
            if p1.element == p2.element:
                _logger.debug('Internal connection')
                combined = ScatteringMatrix()
                combined.s = innerconnect_s(p1.element.s, p1.index, p2.index)
                pinlist = p1.pinlist
                pinlist.remove(p1, p2)
                combined.pinlist = pinlist
            else:
                _logger.debug('External connection')
                combined = ScatteringMatrix()
                combined.s = connect_s(p1.element.s, p1.index, p2.element.s,
                                       p2.index)
                pinlist = p1.pinlist + p2.pinlist
                pinlist.remove(p1, p2)
                combined.pinlist = pinlist
        return combined
예제 #2
0
import matplotlib.pyplot as plt
import numpy as np

from simphony.library import ebeam, sipann
from simphony.connect import innerconnect_s, connect_s
from simphony.simulation import freq2wl, wl2freq

# First, we'll set up the frequency range we wish to perform the simulation on.
freq = np.linspace(wl2freq(1600e-9), wl2freq(1500e-9), 2000)

# Get the scattering parameters for each of the elements in our network.
half_ring_left = sipann.sipann_dc_halfring(radius=10).s_parameters(freq)
half_ring_right = sipann.sipann_dc_halfring(radius=10).s_parameters(freq)
term = ebeam.ebeam_terminator_te1550().s_parameters(freq)

### CONFIGURATION 1 ###
n1 = connect_s(half_ring_left, 1, half_ring_right, 3)
n2 = innerconnect_s(n1, 2, 4)
n3 = connect_s(n2, 1, term, 0)

### CONFIGURATION 2 ###
m1 = connect_s(half_ring_right, 1, half_ring_left, 3)
m2 = innerconnect_s(m1, 2, 4)
m3 = connect_s(term, 0, m2, 3)

plt.plot(freq, np.abs(n3[:, 1, 2])**2, 'b.')
plt.plot(freq, np.abs(m3[:, 0, 1])**2, 'r--')
plt.tight_layout()
plt.show()
예제 #3
0
    def _s_parameters(
        self,
        freqs: "np.array",
        s_parameters_method: str = "s_parameters",
    ) -> "np.ndarray":
        """Returns the scattering parameters for the subcircuit.

        This method will combine the s-matrices of the underlying
        components using the subnetwork growth algorithm.

        Parameters
        ----------
        freqs :
            The list of frequencies to get scattering parameters for.
        s_parameters_method :
            The method name to call to get the scattering parameters.
            Either 's_parameters' or 'monte_carlo_s_parameters'
        """
        from simphony.simulators import Simulator

        all_pins = []
        available_pins = []
        s_block = None

        # merge all of the s_params into one giant block diagonal matrix
        for component in self._wrapped_circuit:
            # simulators don't have scattering parameters
            if isinstance(component, Simulator):
                continue

            # get the s_params from the cache if possible
            if s_parameters_method == "s_parameters":
                try:
                    s_params = self.__class__.scache[component]
                except KeyError:
                    s_params = getattr(component, s_parameters_method)(freqs)
                    self.__class__.scache[component] = s_params
            elif s_parameters_method == "monte_carlo_s_parameters":
                # don't cache Monte Carlo scattering parameters
                s_params = getattr(component, s_parameters_method)(freqs)

            # merge the s_params into the block diagonal matrix
            if s_block is None:
                s_block = s_params
            else:
                s_block = create_block_diagonal(s_block, s_params)

            # keep track of all of the pins (in order) in the circuit
            all_pins += component.pins
            available_pins += component.pins

        # use the subnetwork growth algorithm for each connection
        for pin in all_pins:
            # make sure pins only get connected once
            # and pins connected to simulators get skipped
            if (pin._isconnected(include_simulators=False)
                    and pin in available_pins
                    and pin._connection in available_pins):
                # the pin indices in available_pins lines up with the row/column
                # indices in the matrix. as the matrix shrinks, we remove pins
                # from available_pins so the indices always line up
                k = available_pins.index(pin)
                l = available_pins.index(pin._connection)

                s_block = innerconnect_s(s_block, k, l)

                available_pins.remove(pin)
                available_pins.remove(pin._connection)

        return s_block