def get_bloch_eigensystem(plot=False):
    """docstring for get_bloch_eigensystem"""
    # get Bloch eigensystem
    K, _, ev, _, v, _ = bloch.get_eigensystem(return_eigenvectors=True,
                                              return_velocities=True,
                                              verbose=True, neumann=False)
    K0, K1 = K[0], K[1]
    ev0, ev1 = ev[0,:], ev[1,:]
    print "chi.shape", ev0.shape

    if plot:
        y = np.linspace(0, 1, len(ev0))
        plt.plot(y, np.abs(ev0)**2, "r-")
        plt.plot(y, np.abs(ev1)**2, "g-")
        plt.xlim(0, 1)
        plt.show()

    z = ev0.view(dtype=float)
    np.savetxt("eigensystem.dat", zip(ev0.real, ev0.imag,
                                        np.ones_like(z)*K0.real,
                                        np.ones_like(z)*K0.imag,
                                        ev1.real, ev1.imag,
                                        np.ones_like(z)*K1.real,
                                        np.ones_like(z)*K1.imag),
                header=('y Re(ev0) Im(ev0) Re(K0) Im(K0) Re(ev1)'
                        'Im(ev1) Re(K1) Im(K1)'))
def raster_eps_delta(N=2.6, pphw=300, eta=0.1, W=1.0, xml="input.xml",
                     xml_template="input.xml_template", eps=[0.01, 0.1, 30],
                     delta=[0.3, 0.7, 50], dryrun=False):

    # k_x for modes 0 and 1
    k0, k1 = [np.sqrt(N**2 - n**2)*np.pi for n in (1, 2)]
    kr = k0 - k1

    # ranges
    eps_range = np.linspace(*eps)
    delta_range = np.linspace(*delta)
    print "eps_range", eps_range
    print "delta_range", delta_range

    # check if eps/delta values can be resolved
    r_ny_eps = (eps_range*(N*pphw+1)).astype(int)
    r_nx_L = (abs(2.*np.pi/(kr + delta_range))*(N*pphw+1)).astype(int)
    print "grid-points per full amplitude eps", r_ny_eps
    print "grid-points per length L", r_nx_L

    print_diff_warning(r_ny_eps, "epsilon")
    print_diff_warning(r_nx_L, "length")

    if dryrun:
        sys.exit()

    def update_boundary(eps, delta):
        L = abs(2*np.pi/(kr + delta))

        # choose discretization such that r_nx < len(x_range)
        r_nx_L = (L*(N*pphw + 1)).astype(int)
        x_range = np.linspace(0, L, r_nx_L)

        # no Delta-phase necessary if looking at loop_type constant!
        WG = Dirichlet(loop_type='Constant', N=N, L=L, W=W, eta=eta)

        xi_lower, xi_upper = WG.get_boundary(x=x_range, eps=eps, delta=delta)
        print "lower.boundary.shape", xi_lower.shape

        np.savetxt("lower.boundary", zip(x_range, xi_lower))
        np.savetxt("upper.boundary", zip(x_range, xi_upper))

        N_file_boundary = len(x_range)
        replacements = {'NAME': CALC_NAME,
                        'LENGTH': str(L),
                        'WIDTH': str(W),
                        'MODES': str(N),
                        'PPHW': str(pphw),
                        'GAMMA0': str(eta),
                        'NEUMANN': "0",
                        'N_FILE_BOUNDARY': str(N_file_boundary),
                        'BOUNDARY_UPPER': 'upper.boundary',
                        'BOUNDARY_LOWER': 'lower.boundary'}

        replace_in_file(xml_template, xml, **replacements)

    # parameters, eigenvalues and eigenvectors
    eps, delta, ev0, ev1 = [[] for n in range(4)]
    for e in eps_range:
        for d in delta_range:
            update_boundary(e, d)
            run_code()
            try:
                # bloch_evals = bloch.get_eigensystem()
                # TODO: why column 0 and not 1 to access right moving modes?
                # bloch_evals = np.array(bloch_evals)[0, :2]
                # if bloch.get_eigensystem is not called with modes, dx, etc.,
                # these values are read from the xml file
                evalsfile = 'Evals.' + CALC_NAME + '.dat'
                bloch_evals, _ = bloch.get_eigensystem(evalsfile=evalsfile)
                bloch_evals = np.array(bloch_evals)[:2]

                ev0.append(bloch_evals[0])
                ev1.append(bloch_evals[1])
                eps.append(e)
                delta.append(d)
                with open(TMP, "a") as f:
                    f.write("{} {} {} {} {} {}\n".format(e, d,
                                                         bloch_evals[0].real,
                                                         bloch_evals[0].imag,
                                                         bloch_evals[1].real,
                                                         bloch_evals[1].imag))
                    # backup output files
                    eps_delta_id = "eps_{:.6f}_delta_{:.6f}".format(e, d)
                    evals_file = "evals_" + eps_delta_id + ".dat"
                    archive("Evals." + CALC_NAME + ".dat", evals_file)
                    xml_file = "xml_" + eps_delta_id + ".dat"
                    archive("input.xml", xml_file, delete=False)
                    os.remove("Evecs." + CALC_NAME + ".dat")
                    os.remove("Evecs." + CALC_NAME + ".abs")
            except Exception as ex:
                print "Evals, evecs or xml file not found: {}".format(ex)

    eps, delta, ev0, ev1 = [np.array(x) for x in (eps, delta, ev0, ev1)]
    np.savetxt("bloch_modes.dat", zip(eps, delta,
                                      ev0.real, ev0.imag,
                                      ev1.real, ev1.imag))
def raster_eps_delta(N=2.6, pphw=300, eta=0.1, W=1.0, xml="input.xml",
                     xml_template="input.xml_template", eps=[0.01, 0.1, 30],
                     delta=[0.3, 0.7, 50], dryrun=False, neumann=0):

    # k_x for modes 0 and 1
    if not neumann:
        k0, k1 = [np.sqrt(N**2 - n**2)*np.pi for n in (1, 2)]
    else:
        k0, k1 = [np.sqrt(N**2 - n**2)*np.pi for n in (0, 1)]

    kr = k0 - k1

    # ranges
    eps_range = np.linspace(*eps)
    delta_range = np.linspace(*delta)
    print "eps_range", eps_range
    print "delta_range", delta_range

    # check if eps/delta values can be resolved
    r_ny_eps = (eps_range*(N*pphw+1)).astype(int)
    r_nx_L = (abs(2.*np.pi/(kr + delta_range))*(N*pphw+1)).astype(int)
    print "grid-points per full amplitude eps", r_ny_eps
    print "grid-points per length L", r_nx_L

    print_diff_warning(r_ny_eps, "epsilon")
    print_diff_warning(r_nx_L, "length")

    if dryrun:
        sys.exit()

    def update_boundary(eps, delta):
        L = abs(2*np.pi/(kr + delta))

        # choose discretization such that r_nx < len(x_range)
        # r_nx_L = (abs(2*np.pi/(kr + delta))*(N*pphw + 1)).astype(int)
        r_nx_L = (L(N*pphw + 1)).astype(int)
        x_range = np.linspace(0, L, r_nx_L)
        if not neumann:
            WG = Dirichlet(loop_type='Constant', N=N, L=L, W=W, eta=eta)
        else:
            WG = Neumann(loop_type='Constant', N=N, L=L, W=W, eta=eta)

        xi_lower, xi_upper = WG.get_boundary(x=x_range, eps=eps, delta=delta)
        print "lower.boundary.shape", xi_lower.shape

        np.savetxt("lower.boundary", zip(x_range, xi_lower))
        np.savetxt("upper.boundary", zip(x_range, xi_upper))

        N_file_boundary = len(x_range)
        replacements = {'LENGTH': str(L),
                        'WIDTH': str(W),
                        'MODES': str(N),
                        'PPHW': str(pphw),
                        'GAMMA0': str(eta),
                        'NEUMANN': neumann,
                        'N_FILE_BOUNDARY': str(N_file_boundary),
                        'BOUNDARY_UPPER': 'upper.boundary',
                        'BOUNDARY_LOWER': 'lower.boundary'}

        replace_in_file(xml_template, xml, **replacements)

    # parameters, eigenvalues and eigenvectors
    # eps, delta, ev0, ev1, overlap = [ [] for n in range(5) ]
    eps, delta, ev0, ev1, overlap = []*5
    tmp = "bloch.tmp"
    for e in eps_range:
        for d in delta_range:
            update_boundary(e, d)
            run_code()
            try:
                # bloch_evals = bloch.get_eigensystem()
                # TODO: why column 0 and not 1 to access right moving modes?
                # bloch_evals = np.array(bloch_evals)[0, :2]
                # if bloch.get_eigensystem is not called with modes, dx, etc.,
                # these values are read from the xml file
                bloch_evals, _, bloch_evecs, _ = bloch.get_eigensystem(return_eigenvectors=True,
                                                                       neumann=neumann)
                bloch_evals, bloch_evecs = [np.array(x)[:2] for x in (bloch_evals, bloch_evecs)]
                bloch_evecs_overlap = (np.abs(bloch_evecs[0]-bloch_evecs[1])**2).sum()
                print "overlap", bloch_evecs_overlap

                ev0.append(bloch_evals[0])
                ev1.append(bloch_evals[1])
                overlap.append(bloch_evecs_overlap)
                eps.append(e)
                delta.append(d)
                with open(tmp, "a") as f:
                    f.write("{} {} {} {} {} {}\n".format(e, d,
                                                         bloch_evals[0].real,
                                                         bloch_evals[0].imag,
                                                         bloch_evals[1].real,
                                                         bloch_evals[1].imag))
                    # backup output files
                    evals_file = "evals_eps_{:.8f}_delta_{:.8f}.dat".format(e, d)
                    archive("Evals.complex_potential.dat", evals_file)
                    os.remove("Evecs.complex_potential.dat")
                    os.remove("Evecs.complex_potential.abs")
                    xml_file = "xml_eps_{:.8f}_delta_{:.8f}.dat".format(e, d)
                    archive("input.xml", xml_file, delete=False)
            except:
                print "Evals, evecs or xml file not found!"
            # tmp.out is not written if job is part of a job-array
            tmp_file = "tmp_eps_{:.8f}_delta_{:.8f}.out".format(e, d)
            archive("tmp.out", tmp_file)
            # be backwards compatible in case no jpg is written
            jpg_file = "jpg_eps_{:.8f}_delta_{:.8f}.jpg".format(e, d)
            archive("pic.geometry.complex_potential.1.jpg", jpg_file)

    eps, delta, ev0, ev1, overlap = [np.array(x) for x in (eps, delta, ev0,
                                                           ev1, overlap)]
    np.savetxt("bloch_modes.dat", zip(eps, delta,
                                      ev0.real, ev0.imag,
                                      ev1.real, ev1.imag, overlap))
def run_single_job(n, xn, epsn, deltan, eta=None, pphw=None, XML=None, N=None,
                   WG=None, loop_direction=None, neumann=None):
    """Calculate the Bloch eigensystem in a separate directory and extract the
    eigenvalues and eigenvectors.

        Returns:
        --------
            K0, K1: complex
               eigenvalues
            ev0, ev1: (N,) ndarray
               eigenvectors
    """

    ID = "n_{:03}_xn_{:08.4f}".format(n, xn)
    print
    print ID

    CWD = os.getcwd()
    DIR = os.path.join(CWD, ID)
    os.makedirs(ID)
    os.chdir(DIR)

    # prepare waveguide and profile
    profile_kwargs = {'eps': epsn,
                      'delta': deltan,
                      'pphw': pphw,
                      'input_xml': XML,
                      'custom_directory': os.getcwd(),
                      'neumann': neumann}
    wg_kwargs_n = {'N': N,
                   'eta': eta,
                   'L': 2*np.pi/(WG.kr + deltan),
                   'init_phase': 0.0,
                   'loop_direction': loop_direction,
                   'loop_type': 'Constant'}
    profile_kwargs.update(wg_kwargs_n)

    ep.profile.Generate_Profiles(**profile_kwargs)

    # run code
    cmd = "solve_xml_mumps_dev"
    greens_code = subprocess.Popen(cmd.split(),
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE)
    greens_code.communicate()

    try:
        # get Bloch eigensystem
        K, _, ev, _, v, _ = bloch.get_eigensystem(return_eigenvectors=True,
                                                  return_velocities=True,
                                                  verbose=True,
                                                  neumann=neumann)
        # remove eigenvalue files
        # os.remove("Evecs.sine_boundary.dat")
        # os.remove("Evecs.sine_boundary.abs")

        # if np.real(v[0]) < 0. or np.real(v[1]) < 0.:
        #     sys.exit("Error: group velocities are negative!" + 180*"-")

        K0, K1 = K[0], K[1]
        ev0, ev1 = ev[0,:], ev[1,:]
        print "chi.shape", ev0.shape

        z = ev0.view(dtype=float)
        np.savetxt("eigensystem.dat", zip(ev0.real, ev0.imag,
                                          np.ones_like(z)*K0.real,
                                          np.ones_like(z)*K0.imag,
                                          ev1.real, ev1.imag,
                                          np.ones_like(z)*K1.real,
                                          np.ones_like(z)*K1.imag),
                   header=('y Re(ev0) Im(ev0) Re(K0) Im(K0) Re(ev1)'
                           'Im(ev1) Re(K1) Im(K1)'))
        os.chdir(CWD)
        # subprocess.call("gzip -r {}".format(DIR).split())
        # shutil.rmtree(DIR)

        print "xn", xn, "epsn", epsn, "deltan", deltan, "K0", K0, "K1", K1
        return K0, K1, ev0, ev1

    except:
        os.chdir(CWD)
        print traceback.print_exc()
        return
예제 #5
0
        parameters = [ (n,m) for n in x0, x1 for m in y0, y1 ]
        # order: (x0, y0) -> (x_i,   y_i)
        #        (x0, y1) -> (x_i,   y_i+1)
        #        (x1, y0) -> (x_i+1, y_i)
        #        (x1, y1) -> (x_i+1, y_i+1)
        if 1:
            for n, (x, y) in enumerate(parameters):
                # we dont need the values lambda_n(x_i+1, y_i+1)
                if n < 3:
                    print "n,m", x, y
                    self._check_numerical_resolution(x)
                    self._update_boundary(x, y)
                    self._run_code()
                    # take the first two right-movers & k1 -> k1 mod kr
                    # TODO: why column 0 and not 1 to access the right moving modes?
                    bloch_modes = np.array(bloch.get_eigensystem())[0,:2]
                    F = np.abs(bloch_modes[0] - bloch_modes[1])
                    print F == np.abs(np.array([1,-1]).dot(bloch_modes))
                    eigenvalues.append(F)
        else:
            # alternative
            pass

        self.evals.append([bloch_modes[0],
                           bloch_modes[1]])
        delta = 0.01
        F = np.asarray(eigenvalues).T

        gradient = np.array([[-1, 0, 1],
                             [-1, 1, 0]])