Exemplo n.º 1
0
def investigate_autocorrelation(
    lattice_sizes,
    max_t: int = 10**6,
    temps=None,
):
    """
    Plots autocorrelation for different temperatures and sizes as a 
    function of time. 

    Parameters:
    -----------
    lattice_sizes: iterable
    
    max_t: int
    Maximum time to run simulations for. 

    temps: iterable

    take_every: int
    Only run for 'take_every'-th lattice size. 

    Returns:
    --------
    List $\tau_e$ , labelled by the temperature, and size. 
    
    """
    if temps is None:
        temps = linspace(1.8, 3.0, 50)
    time = linspace(0, max_t, 50, dtype=int)
    fig, axes = plt.subplots(nrows=len(lattice_sizes),
                             sharex='col',
                             sharey='col')
    tau_e, print_interval = [], int(len(temps) / 5)
    for ax, l in zip(axes, tqdm(lattice_sizes)):
        t_e, counter = [], 0
        for temp in tqdm(temps):
            s = Simulation(duration=max_t, lattice_size=l, temperature=temp)
            autocorr, sigma_autocorr = generate_autocorr_data(s, time)
            t_e.append(find_tau_e(autocorr, time, max_t))
            if counter % print_interval == 0:
                plot_autocorrelation(autocorr, sigma_autocorr, ax, s, time)
            counter += 1
        tau_e.append(t_e)
    tau_e = array(tau_e)
    plt.xlabel(r'$\tau$')
    fig.set_size_inches(10.5, 10.5)
    save_plot('Autocorrelation', legend_loc='upper right')
    plt.errorbar(temps, mean(tau_e, axis=0), yerr=std(tau_e, axis=0), fmt='-')
    plt.axvline(x=t_c)
    plt.xlabel('temperature / (J / $k_B$)')
    plt.ylabel(r'$\tau_e$ / time steps')
    save_plot('Coherence lifetime vs. temperature')
    plt.errorbar(lattice_sizes,
                 mean(tau_e, axis=1),
                 yerr=std(tau_e, axis=1),
                 fmt='.')
    plt.xlabel('Lattice size / arb. units')
    plt.ylabel(r'$\tau_e$ / time steps')
    save_plot('Coherence lifetime vs. lattice size')
    return tau_e
Exemplo n.º 2
0
def generate_data(
    temps: iter,
    size=32,
    hs=0,
    r1=3,
    r2=4,
    **kwargs,
):
    global use_disk
    use_disk = False
    simulations = [
        Simulation(magnetic_field=hs,
                   lattice_size=size,
                   temperature=t,
                   dry_run=True) for t in temps
    ]
    data = parmap(lambda s: multi_run(s, **kwargs),
                  tqdm(simulations, desc='Temperature samples'))
    sigmas = array(data).T[r1]
    meta_sigmas = array(data).T[r2]
    if r1 == 3:
        data = array([
            sigma**2 / (temp**2) * size**2
            for temp, sigma in zip(temps, sigmas)
        ])
    elif r1 == 1:
        data = array([
            sigma**2 / (temp**2) * size**2
            for temp, sigma in zip(temps, sigmas)
        ])
    else:
        data = sigmas
    sigma_data = data[:] * meta_sigmas[:]
    return data, sigma_data
Exemplo n.º 3
0
def investigate_magnetisation_critical_transitions(lattice_sizes,
                                                   temps=None,
                                                   **kwargs):
    """
    Plot the magnetisation and mean energy as a function of temperature. 
    Determine critical temperature by approximating the transition to a
    Fermi-Dirac distribution.
    
    Returns:
    --------
    List of critical temperatures. 
    """
    if temps is None:
        temps = linspace(1.2, 3, 32)
    fig, ax = plt.subplots(nrows=2, sharex='col')
    ax[0].set_ylabel('magnetisation / spin')
    ax[1].set_ylabel('energy per spin/ J')
    ax[0].axvline(x=t_c, color='k', ls='--')
    ax[1].axvline(x=t_c, color='k', ls='--')
    res = []
    for l in tqdm(lattice_sizes):
        simulations = [
            Simulation(lattice_size=l,
                       temperature=t,
                       duration=smart_duration(l, t),
                       dry_run=True) for t in temps
        ]
        data = parmap(lambda s: multi_run(s, **kwargs), tqdm(simulations))
        terminal_magnetisations = array(data).T[0]
        # The data.T[1] holds the relative errors, not absolute ones.
        sigma_magnetisations = array(data).T[1]
        sigma_magnetisations = terminal_magnetisations * sigma_magnetisations
        terminal_energies = array(data).T[2]
        ax[0].errorbar(temps,
                       terminal_magnetisations,
                       yerr=sigma_magnetisations,
                       fmt='-',
                       label='N = ' + str(l))
        ax[1].plot(temps, terminal_energies, '-', label='N =' + str(l))
        popt, _ = curve_fit(magnetisation_fit, temps, terminal_magnetisations)
        res.append(popt[0])
    plt.xlabel('temperature / J')
    plt.xticks(
        append(linspace(min(temps), t_c, 3), linspace(t_c, max(temps), 3)))
    save_plot('Critical temperature from magnetisation')
    return res
Exemplo n.º 4
0
def investigate_chi(temps, sizes):
    """
    Produce a plot of magnetic susceptibility vs temperature.
    Returns list of critical transition temperatures.
    """
    plot_magnetic_response(temps)
    t_cs = []
    for size in tqdm(sizes):
        chi_data = array([chi(t, size) for t in tqdm(temps)]).T
        chis, chierrs = chi_data[0], chi_data[1]
        plt.errorbar(temps, chis, yerr=chierrs, label=str(size), fmt='+')
        t_cs.append(temps[argmax(chis)])
    plt.axvline(x=t_c)
    plt.ylabel('susceptibility / spin')
    plt.xlabel('temperature / (J/$k_B$)')
    save_plot('Susceptibility vs Temperature')
    return t_cs
Exemplo n.º 5
0
def investigate_heat_capacity(lattice_sizes, temps=None, skip=3, **kwargs):
    """
    Plot the heat capacity versus temperature for different lattice sizes.
    Find the critical temperature for each size by doing a spline smoothing
    and finding the peak. 

    Parameters: 
    -----------
    lattice_sizes: iterable

    temps: iterable 

    **kwargs: keyword_arguments
    Arguments to be passed to multi_run()

    Returns: 
    List of critical temperatures. 
    """
    if temps is None:
        temps = append(linspace(1.6, 4.25, 12), linspace(1.8, 2.8, 24))
        temps.sort()

    fig, _ = plt.subplots()
    crit_temps, counts = [], 0
    for l in tqdm(lattice_sizes, desc='Lattice sizes'):
        for t in temps:
            pass
        caps, cap_errs = generate_data(
            temps,
            l,
            **kwargs,
        )
        up_temps, up_caps = upscale(caps, temps)
        main_peak = argmax(up_caps)
        crit_temps.append(up_temps[main_peak])
        counts += 1
        if counts % skip == 0:
            plt.errorbar(temps,
                         caps,
                         fmt='+',
                         yerr=cap_errs,
                         label='N = ' + str(l))
            plt.plot(
                up_temps[main_peak],
                up_caps[main_peak],
                'bo',
            )
            plt.plot(up_temps, up_caps, label='N = ' + str(l) + ' smoothed')

            plt.xticks(
                append(linspace(min(temps), t_c, 3),
                       linspace(t_c, max(temps), 4)))
    plt.ylabel(r'$C_V/ k_B$')
    plt.axvline(x=t_c, ls='-.', color='k')
    fig.set_size_inches([10.5, 10.5])
    plt.xlabel('temperature / $J/ k_B$')
    save_plot('Heat capacity', )
    return crit_temps
Exemplo n.º 6
0
def plot_magnetic_response(temps):
    """Plot magnetisation vs H, for different temperatures."""
    counts = 0
    p = int(len(temps) / 6)
    for t in tqdm(temps):
        chi(t, sz=64, plot_q=(counts % p == 0))
        counts += 1
    plt.ylabel('Magnetisation / spin')
    plt.xlabel('Applied field / (J/$\mu$)')
    save_plot('Magnetisation vs. external field')
Exemplo n.º 7
0
def investigate_magnetic_fluctuations(hs, temps=None, skip=3, **kwargs):
    """
    Plot the magnetic  susceptibility versus temperature for different
    lattice sizes. Find the critical temperature for each H by spline
    interpolation and finding the maximum.

    Parameters:
    -----------
    hs: iterable

    temps: iterable

    **kwargs: keyword_arguments
    Arguments to be passed to multi_run()

    Returns:
    List of critical temperatures.
    """
    if temps is None:
        temps = append(linspace(1.6, 3.9, 12), linspace(1.8, 2.8, 24))
        temps.sort()

    fig, _ = plt.subplots()
    crit_temps, counts = [], 0
    for h in tqdm(hs, desc='External fields.'):
        # get upscaled and smoothed capacity vs temperature data.
        mags, _ = generate_data(temps, hs=h, r1=1, r2=1, **kwargs)
        up_temps, up_mags = upscale(mags, temps)
        main_peak = argmax(up_mags)
        plt.plot(
            up_temps[main_peak],
            up_mags[main_peak],
            'bo',
        )
        crit_temps.append(up_temps[main_peak])
        counts += 1
        if counts % skip == 0:
            plt.plot(temps, mags, 'b+', label=r'$\vec{H}$ = ' + str(h))
            plt.plot(up_temps, up_mags, label='N = ' + str(h) + ' smoothed')
            plt.ylabel(r'$\chi/ (\mu/J)')
            plt.axvline(x=t_c, ls='-.', color='k')
            plt.xticks(
                append(linspace(min(temps), t_c, 3),
                       linspace(t_c, max(temps), 6)))
    fig.set_size_inches(8.5, 8.5)
    fig.tight_layout()
    plt.xlabel('temperature / (J/$k_B$')
    save_plot('Magnetic susceptibility')
    return crit_temps