Exemplo n.º 1
0
    def func(T):
        if T > 0.6:
            return -1
        #print "    @ T =", T, ":"
        geometry.t_t = T
        geometry.w_delta = last_gtr_delta[0]

        it = u.self_consistent_matsubara_iteration(geometry,
                                                   output_func=None,
                                                   **kw)

        for k, d, v in it:
            rel_err = d.residual_norm() / abs(d.get()).max()
            #sys.stdout.write("%g(%.1g)  " % (rel_err, abs(d.get()).max()))
            #sys.stdout.flush()
            if rel_err < 1e-3 and v < 1e-4:
                break
            if abs(d.get()).max() < tol:
                geometry.w_delta = 0.0
                geometry.w_phase = 0.0
                break

        dmax = abs(geometry.w_delta).max()
        if dmax == 0:
            #sys.stdout.write("=> N\n")
            return -1
        last_gtr_delta[0] = geometry.w_delta.copy()
        #sys.stdout.write("=> S (%g)\n" % dmax)
        return dmax
def test_bilayer_matsubara():
     global g, Delta_0, omega_D, lambda_0, d_A, d_B

     g.w_delta[...] = Delta_0

     Delta_1 = bilayer_delta(lambda_0, omega_D, d_A, d_B)

     # Note: again need the whole energy range up to omega_D,
     #       because the Thouless energy is much larger than the enery gap
     #       and omega_D!
     it = u.self_consistent_matsubara_iteration(g, max_ne=200)

     for k, d, violation in it:
          print "Iter %d: relative residual %.2g" % (
               k, d.relative_residual_norm())

          if (d.relative_residual_norm() < 1e-4 and violation < 1e-5):
               break
     else:
          raise RuntimeError("Did not converge")

     assert allclose(g.w_delta[0,:], Delta_1, rtol=1e-2), g.w_delta[0,0]
    def func(T):
        print "    @ T =", T, ":"
        geometry.t_t = T
        geometry.w_delta = last_gtr_delta[0]

        if matsubara:
            it = u.self_consistent_matsubara_iteration(geometry,
                                                       output_func=None,
                                                       **kw)
        else:
            solver = u.CurrentSolver(geometry)
            it = u.self_consistent_realtime_iteration(solver, output_func=None,
                                                      **kw)

        zero_count = 0
        for k, d, v in it:
            rel_err = d.residual_norm() / abs(d.get()).max()
            sys.stdout.write("%g(%.2g)  " % (rel_err, abs(d.get()).max()))
            sys.stdout.flush()
            if abs(d.get()).max() < 1e-3:
                zero_count += 1
            else:
                zero_count = 0
            if zero_count > 4:
                geometry.w_delta = 0.0
                geometry.w_phase = 0.0
                break
            if rel_err < 1e-4 and v < 1e-4:
                break

        dmax = abs(geometry.w_delta).max()
        if dmax == 0:
            sys.stdout.write("=> N\n")
            return -1
        last_gtr_delta[0] = geometry.w_delta.copy()
        sys.stdout.write("=> S (%g)\n" % dmax)
        return dmax
def main():
    g = get_geometry(pi/2)

    file_name = 'nonlocal_thermovoltage_spectral.h5'

    # It is possible to do a self-consistent iteration, but this is quite
    # slow.
    #
    # Change False to True below, if you want to try that:
    do_selfconsistent_iteration = False

    # Load data from a file, if it exists
    solver = u.CurrentSolver.resume(file_name, g, ne=200, chunksize=50)
    solver.set_solvers(kin_solver=u.KIN_SOLVER_BLOCK,
                       sp_solver=u.SP_SOLVER_TWPBVP)

    # Solve and save spectral quantities to a file.
    # This takes some time, so we'll want to avoid redoing it unnecessarily.
    #
    # calculage_G=True instructs the solver also to calculate a spectral
    # conductance matrix for the circuit, which can be used to conveniently
    # evaluate currents given distribution functions in the terminals.
    #
    if not do_selfconsistent_iteration:
        solver.solve_spectral_and_save_if_needed(file_name, calculate_G=True)
 

    # Solve thermovoltage vs. temperature
    dT = 0.05

    # ... and write results to a text file
    output = open('nonlocal_thermovoltage.dat', 'w')
    print >> output, "%% %14s %14s" % ("T (E_T)", "dV/dT (ueV/K)")

    if do_selfconsistent_iteration:
        Ts = logspace(log10(dT + 1e-4), log10(10), 15)[1:]
    else:
        Ts = logspace(log10(dT + 1e-4), log10(10), 100)

    for T in Ts:
        
        # (Optional) self-consistent iteration
        if do_selfconsistent_iteration:
            g.t_mu = 0
            g.t_t = T
            it = u.self_consistent_matsubara_iteration(g, max_ne=50)
            #it = u.self_consistent_realtime_iteration(solver)
            for k, d, I_error in it:
                print >> sys.stderr, "%% Self-consistent iteration %d (residual %g)" % (k, d.residual_norm())
                if (d.residual_norm() < 1e-3 * 100 and I_error < 1e-5):
                   break
            else:
                raise RuntimeError("Self-cons. iteration didn't converge!")

            solver.solve_spectral()
            solver.calculate_G()
            solver.save("nonlocal_thermovoltage_T_%.2f.h5" % T)

        # Compute the thermovoltage:
        g.t_mu = 0
        g.t_t = T
        g.t_t[11] += dT

        # Make the terminals 0, 3, 4, 5, 11 to float
        # Currents entering them flow in wires 0, 3, 4, 5, 7
        
        def zero_currents():
            Ic, Ie = solver.get_currents_from_G(w_jT=[0,3,4,5,7], w_jL=[])
            #Ic, Ie = solver.get_currents(w_jT=[0,3,4,5,7], w_jL=[], ix=0)
            return [Ic[0], Ic[3], Ic[4], Ic[5], Ic[7]]

        def set_potentials(z):
            g.t_mu[0], g.t_mu[3], g.t_mu[4], g.t_mu[5], g.t_mu[11] = z

        u.optimize_parameters_for([0,0,0,0,0], zero_currents, set_potentials)

        # Print the thermovoltage at terminal 4 in ueV/K
        print >> output, "  %14g %14g" % (T, g.t_mu[4] / dT * 86.17343)

    # Solve the kinetic equations for some temperature and a larger
    # temperature difference, and dump the result for inspection.
    g.t_t = 1e-4
    g.t_t[11] = 8

    solver.solve_kinetic()
    solver.save('dump.h5')

    output.close()