コード例 #1
0
    def _get_parameters(self):
        """Return the waveguide parameters for a given number of open modes N."""

        if self.verbose:
            print json.dumps(vars(self), sort_keys=True, indent=4)

        with open("potential.cfg", "w") as f:
            data = json.dumps(vars(self), sort_keys=True, indent=4)
            f.write(data)

        wg_kwargs = {'N': self.N,
                     'L': self.L,
                     'W': self.W,
                     'tN': self.nx/self.L,
                     'loop_type': self.loop_type,
                     'x_R0': self.x_R0,
                     'y_R0': self.y_R0,
                     'init_phase': self.init_phase,
                     'theta': self.theta,
                     'linearized': self.linearized}
        self.WG = DirichletPositionDependentLoss(**wg_kwargs)

        self.kF = self.WG.k0
        self.kr = self.WG.kr

        if self.direction == 'left':
            self.sign = -1
        else:
            self.sign = 1

        if self.shape == 'science':
            print "Science system size fixed at 4.5*lambda."
            self.L = 4.5*2*np.pi/self.kr

        x = self.WG.t
        y = np.linspace(0.0, self.W, self.ny)
        self.X, self.Y = np.meshgrid(x, y)

        self.X0 = np.ones_like(self.X)*np.pi/self.kr

        if self.verbose:
            print "L:", self.L
            print "eta:", self.WG.eta
            print "nx:", len(self.WG.t)
            print "ny:", len(y)
            print "2pi/kr:", 2.*np.pi/self.kr
コード例 #2
0
class Potential(object):
    """Basic class to return a spatially dependent potential.

        Parameters:
        -----------
            N: float
                Number of open modes.
            pphw: int
                Points per half wavelength.
            amplitude: float
                Potential strength.
            sigmax: float
                Smoothing width of the potential in x-direction.
            sigmay: float
                Smoothing width of the potential in y-direction.
            W: float
                Waveguide W.
            x_R0: float
                Waveguide loop parameter.
            y_R0: float
                Waveguide loop parameter.
            init_phase: float
                Initial phase/position in frequency space.
            loop_type: str
                Loop parametrization identifier.
            shape: str
                Potential type.
            direction: str
                Injection direction (left|right).
            with_boundary: bool
                Whether to shift the potential positions with the profile
                boundary.

        Attributes:
        -----------
            imag: (Nx,Ny) ndarray
            real: (Nx,Ny) ndarray
            imag_vector: (Nx*Ny,1) ndarray
            real_vector: (Nx*Ny,1) ndarray
            X, Y: (Nx,Ny) ndarray
    """

    def __init__(self, N=2.5, pphw=20, amplitude=1.0, sigmax=1e-1, sigmay=1e-1,
                 L=100, W=1., x_R0=0.05, y_R0=0.4, init_phase=0.0, loop_type='Bell',
                 shape='RAP', direction='right', boundary_only=False,
                 with_boundary=False, theta=None, verbose=True, linearized=False):
        self.N = N
        self.pphw = pphw
        self.nx = int(L*(pphw*N+1)/W)
        self.ny = int(pphw*N+1)
        self.amplitude = amplitude
        self.sigmax = sigmax
        self.sigmay = sigmay
        self.shape = shape
        self.L = L
        self.W = W
        self.x_R0 = x_R0
        self.y_R0 = y_R0
        self.init_phase = init_phase
        self.loop_type = loop_type
        self.direction = direction
        self.with_boundary = with_boundary
        self.theta = theta
        self.verbose = verbose
        self.linearized = linearized

        self._get_parameters()
        if not boundary_only:
            self.imag = self._get_imag_potential()
            self.real = self._get_real_potential()
            self.imag_vector = self._array_to_vector(self.imag)
            self.real_vector = self._array_to_vector(self.real)

    def _get_parameters(self):
        """Return the waveguide parameters for a given number of open modes N."""

        if self.verbose:
            print json.dumps(vars(self), sort_keys=True, indent=4)

        with open("potential.cfg", "w") as f:
            data = json.dumps(vars(self), sort_keys=True, indent=4)
            f.write(data)

        wg_kwargs = {'N': self.N,
                     'L': self.L,
                     'W': self.W,
                     'tN': self.nx/self.L,
                     'loop_type': self.loop_type,
                     'x_R0': self.x_R0,
                     'y_R0': self.y_R0,
                     'init_phase': self.init_phase,
                     'theta': self.theta,
                     'linearized': self.linearized}
        self.WG = DirichletPositionDependentLoss(**wg_kwargs)

        self.kF = self.WG.k0
        self.kr = self.WG.kr

        if self.direction == 'left':
            self.sign = -1
        else:
            self.sign = 1

        if self.shape == 'science':
            print "Science system size fixed at 4.5*lambda."
            self.L = 4.5*2*np.pi/self.kr

        x = self.WG.t
        y = np.linspace(0.0, self.W, self.ny)
        self.X, self.Y = np.meshgrid(x, y)

        self.X0 = np.ones_like(self.X)*np.pi/self.kr

        if self.verbose:
            print "L:", self.L
            print "eta:", self.WG.eta
            print "nx:", len(self.WG.t)
            print "ny:", len(y)
            print "2pi/kr:", 2.*np.pi/self.kr

    def _get_imag_potential(self):
        """Return a complex potential."""
        X, Y = self.X, self.Y
        X0 = self.X0
        sigmax = self.sigmax
        sigmay = self.sigmay
        amplitude = self.amplitude
        imag = np.zeros_like(X)

        if self.shape == 'science':
            imag = np.sin(self.sign*self.kr*(X - X0))
            imag[Y > Y.mean()] = 0.
            if self.direction == 'left':
                imag[X < (self.L - 4*2*np.pi/self.kr)] = 0.
                imag[X > (self.L - 2*np.pi/self.kr)] = 0.
            else:
                imag[X > 4*2*np.pi/self.kr] = 0.
                imag[X < 2*np.pi/self.kr] = 0.
            imag[imag < 0.] = 0.
        elif self.shape == 'RAP':
            xnodes, ynodes = self.WG.get_nodes_waveguide()
            if self.with_boundary:
                ynodes += -self.WG.get_boundary(xnodes)[0]

            for (xn, yn) in zip(xnodes, ynodes):
                if np.isfinite(xn) and np.isfinite(yn):
                    # greens_code counts from top to bottom: yn -> W - yn
                    # imag += gauss(X, xn, self.sigmax)*gauss(Y, self.WG.W - yn, self.sigmay)
                    imag += gauss(X, xn, self.sigmax)*gauss(Y, yn, self.sigmay)
            self.xnodes = xnodes
            self.ynodes = ynodes
        else:
            imag = np.ones_like(X)

        imag *= -self.kF/2. * amplitude

        return imag

    def _get_real_potential(self):
        """Return a real potential."""
        X, Y = self.X, self.Y
        X0 = self.X0
        sigmax = self.sigmax
        sigmay = self.sigmay
        amplitude = self.amplitude

        if self.shape == 'science':
            real = np.sin(self.sign*self.kr*(X - (X0 + np.pi/(2.*self.kr))))
            real[Y < Y.mean()] = 0.
            real[real < 0.] = 0.
            if self.direction == 'left':
                real[X < (self.L - 4*2*np.pi/self.kr - np.pi/(2*self.kr))] = 0.
                real[X > (self.L - 2*np.pi/self.kr - np.pi/(2*self.kr))] = 0.
            else:
                real[X > 4*2*np.pi/self.kr + np.pi/(2*self.kr)] = 0.
                real[X < 2*np.pi/self.kr + np.pi/(2*self.kr)] = 0.
            real *= self.kF/2. * amplitude
        else:
            real = np.zeros_like(X)

        return real

    def _array_to_vector(self, Z):
        """Turn a NxN matrix into a N*Nx1 array."""

        return Z.flatten(order='F')