Пример #1
0
def check_shuffle_file():
    """ Check for a file for shuffled indices. Create a new one if not. """

    # Check if shuffle file exists
    input_file = "shuffled_indices.out"
    if os.path.exists(input_file) != True:
        
        # Any existing disp files should be deleted if the shuffle file has been lost
        disp_file = alg.file_names('input', 0, 0)['d']
        if os.path.exists(disp_file) == True:
            error(this_file, "Unfortunately, since the shuffle file has been lost, the initial displacement vectors must be reset to zero. Please move or delete files %s etc." %disp_file)
    
        # Create a new array and file for shuffled indices
        shuffled_indices = np.arange(Natoms)
        np.random.shuffle(shuffled_indices)
        print "Saving new shuffled indices to ", input_file
        np.savetxt(input_file, shuffled_indices.astype(int), fmt='%i')
Пример #2
0
if TRAP == True:
    Ns_eff = Ns  # multiple procs on same subdomain already combined in join_procs
else:
    Ns_eff = 1  # there may be more than 1 subdom, but each process is global - simulation has access to entire domain

# ----------------------------------- #
#  Iterate over different subdomains  #
# ----------------------------------- #
for s in range(Ns_eff):

    print ""
    if TRAP == True: print "Series data from subdomain: ", s
    else: print "Series data from global domain."

    # Load the series data
    input_file = alg.file_names('pcomb', s)['s']
    input_data = np.loadtxt(input_file)

    # Unpack
    subdom = np.array(input_data[:, 0], dtype=np.int)
    mu = input_data[:, 1]
    weights = input_data[:, 2]
    E_active = input_data[:, 3]

    # Number of bins, mu positions of bins
    if TRAP == True:
        N_bins = dom.subdom[s]['bins']
        mu_bins = dom.get_local_mu_bins(s)
    else:
        N_bins = np.sum(bins)
        mu_bins = dom.get_global_mu_bins()
Пример #3
0
def gen_input_files():
    """ If starting a new fixed-weights simulation, empty files will need
    to be created to be imported during the first loop iteration. """
   
    if algorithm not in ('multicanonical', 'transition'):
        return

    print ""

    for p in range(Np):
        # Map to subdomain index
        s = ini.map_proc_to_subdom(p)

        # Input files as decided by program
        input_files = alg.file_names('input', s, p)

        sname, pname = ini.naming_system(s, p)

        # User input files from params
        params_input_files = {'d': None,
                           'w': params_weights_file,
                           'h': params_hist_file,
                           'c': params_Cmat_file,
                           's': params_series_file,}
        # Check if we need to add '_pY_sX'
        params_weights_file_alt = ini.rename_inputs(params_weights_file, sname[0], '')
        params_hist_file_alt = ini.rename_inputs(params_hist_file, sname[0], pname[0])
        params_Cmat_file_alt = ini.rename_inputs(params_Cmat_file, sname[0], pname[0])
        params_series_file_alt = ini.rename_inputs(params_series_file, sname[0], pname[0])
        params_input_files_alt = {'d': None,
                               'w': params_weights_file_alt, 
                               'h': params_hist_file_alt,
                               'c': params_Cmat_file_alt,
                               's': params_series_file_alt}

        # Correct sizes
        size = ini.get_size(s)
        start_files = {'d': np.zeros((Natoms, 3)), 
                'w': np.zeros(size), 'h': np.zeros(size), 
                'c': np.zeros((size,size)), 's': [np.ones(5)*-1,]}
      
        for key in params_input_files.keys():
            # If an input file has been given in params.py
            if params_input_files[key] != None:
                # If the default input file doesn't yet exist,
                # We need to save a copy of the params file to this name
                if os.path.exists(input_files[key]) == False:
                    # First check for the params file modified by '_pY_sX'
                    if os.path.exists(params_input_files_alt[key]) == True:
                        tmp = np.loadtxt(params_input_files_alt[key])
                        print "     Copying %s -> %s" %(params_input_files_alt[key], input_files[key])
                        np.savetxt(input_files[key], tmp)
                    # Then check for the exact file name given in params.py 
                    elif os.path.exists(params_input_files[key]) == True:
                        tmp = np.loadtxt(params_input_files[key])
                        print "     Copying %s -> %s" %(params_input_files[key], input_files[key])
                        np.savetxt(input_files[key], tmp)
                    # Error if params file hasn't been found
                    else:
                        error(this_file, "     Neither files %s or %s not found." %(params_input_files_alt[key],params_input_files[key]))

                # If the default input file does exist, leave it alone
                else: 
                    print "     File %s exists and will be read as input" %input_files[key]
        
    
    print ""

    print "File check completed. "
    return
Пример #4
0
# ------------------------------------------- #
#  Compile a list of input/output file names  #
# ------------------------------------------- #
# Check for sensible argv[1]
if argv[1] not in ('w', 'c', 'h'):
    error(this_file, "argv[1] should be 'w', 'c', or 'h'")

# Input file names for each subdomain
input_file_list = []
for s in range(Ns):

    if len(argv) > 2:  # file stem passed as argument
        input_file = argv[2] + "_s" + str(s) + ".out"
    else:  # default file names
        input_file = alg.file_names(stage_in, s)[argv[1]]

    input_file_list.append(input_file)

# Output file name
if len(argv) > 2:  # use argument file stem as output file stem
    output_file = argv[2] + "_scomb.out"
else:
    output_file = alg.file_names('scomb')[argv[1]]


# --------------------------------------------- #
#  Optional: plot all subdomains in one figure  #
# --------------------------------------------- #
def plot_combined(data_list, mu_list):
    ''' Plot combined subdomain data, either joined up or not '''
Пример #5
0
    if save == True:
        global_diffusivity = []

    # ------------------------- #
    #  Iterate over subdomains  #
    # ------------------------- #
    for s in range(Ns_eff):

        # Initialise arrays for combined data within subdom
        size = ini.get_size(s)
        hist = np.zeros(size)
        cuts = np.zeros(size)

        for p in p_list[s::Ns_eff]:
            # Get file names to load
            input_files = alg.file_names('output', s, p)
            extra_input_files = dyn.file_names('output', s, p)

            # Load input files
            this_hist = np.loadtxt(input_files['h'])
            this_cuts = np.loadtxt(extra_input_files['cu'])
            
            # Add to combined
            hist = hist + this_hist
            cuts = cuts + this_cuts
            
        if TRAP == True:
            # Scale by bin width
            cuts = cuts * dom.subdom[s]['bin_width']
            # Load mu subdomain
            mu_bins = dom.get_local_mu_bins(s) * B / float(Natoms)
Пример #6
0
    size = ini.get_size(s)
    steps = ls.run(atoms_alpha,
                   atoms_beta,
                   disp, {
                       'w': np.zeros(size),
                       'h': np.zeros(size),
                       'c': np.zeros((size, size))
                   },
                   dyn_data,
                   p,
                   s,
                   relax=True)

    # Separate independent runs by saving this line to the series output file
    if track_series == True:
        series_file = alg.file_names('output', s, p)['s']
        series = open(series_file, 'a')
        series.write("-1 -1 -1 -1 \n")
        series.close()

###################################################################################
##                                                                               ##
##                   Run a Lattice-switch Monte Carlo simulation                 ##
##                      by calling lattice_switch.run()                          ##
##                                                                               ##
###################################################################################

###################
##  Wang-Landau  ##
###################
if algorithm == 'wang_landau':
Пример #7
0
ax.set_ylabel(r"$E \times \beta/N$")

# Colours distinguish between subdomains
colours = ('tab:gray', 'k')

# Initialise arrays for averaging energy
E_mean = np.zeros(np.sum(bins))
counts = np.zeros(np.sum(bins))

# ----------------------------------- #
#  Iterate over different subdomains  #
# ----------------------------------- #
for s in range(Ns_eff):

    # Load the series data
    input_file = alg.file_names('pcomb', s)['s']
    input_data = np.loadtxt(input_file)

    # Unpack
    subdom = np.array(input_data[:, 0], dtype=np.int)
    mu = input_data[:, 1]
    weights = input_data[:, 2]
    E_active = input_data[:, 3]

    # Decide how frequently we want to add a point to the scatter plot
    Nrows = len(subdom)
    addpoint = int(Nrows / points_per_sub)

    # Initialise lists for scatter data
    E_scatter = []
    mu_scatter = []
Пример #8
0
def run(atoms_alpha,
        atoms_beta,
        disp,
        binned_data,
        dyn_data,
        p,
        s,
        F=1,
        relax=False):

    # ------------------------------------------------- #
    #  Set simulation parameters and useful quantities  #
    # ------------------------------------------------- #
    lendata = len(binned_data['w'])  # length of weights
    kTlogF = kT * np.log(F)

    # Convert frequency parameters from sweeps to steps
    if relax == True:
        Nsteps = sweeps_relax * Natoms
    else:
        Nsteps = alg.Nsteps
    save_step = sweeps_save * Natoms
    series_step = int(sweeps_series * Natoms)
    recalc_step = sweeps_recalc * Natoms
    refresh_step = sweeps_refresh * Natoms

    # Set boundaries for this simulation
    if TRAP == True:  # restrict to subdomain 's'; local bin indices
        global_mu_min = dom.subdom[s]['min']
        global_mu_max = dom.subdom[s]['max']
        get_index = dom.get_local_index
        mu_bins = dom.get_local_mu_bins(s)
    else:  # can access entire domain; global bin indices
        global_mu_min = boundaries[0]
        global_mu_max = boundaries[-1]
        get_index = dom.get_global_index
        mu_bins = dom.get_global_mu_bins()

    # Set weights function
    if use_interpolated_weights == True:
        get_weight = interpolated_weight

        # Need to add bins to the edges of mu and weights for extrapolation
        mu_bins = np.concatenate((mu_bins, [0, 0]))
        extrapolate(mu_bins)
        binned_data['w'] = np.concatenate((binned_data['w'], [0, 0]))
        extrapolate(binned_data['w'])

        # Need to do the same for cuts since it uses mu_bins
        if track_dynamics == True:
            dyn_data['cu'] = np.concatenate((dyn_data['cu'], [0, 0]))

    else:
        get_weight = discrete_weight

    # ------------------------ #
    #  Initialise usual stuff  #
    # ------------------------ #
    # Get initial lattice energies and difference between them
    old_E_alpha, old_E_beta = lattice_energies(atoms_alpha, atoms_beta)
    old_mu = old_E_alpha - old_E_beta
    new_mu = old_mu

    # For a global simulation, the initial subdomain (corresponding to the
    # input disp vector) needs to be computed
    if TRAP != True:
        s = dom.get_subdomain(old_mu)

    # Initial index and weight
    old_index = get_index(old_mu, s)
    old_weight = get_weight(old_mu, old_index, mu_bins, binned_data['w'])

    # Active lattice
    if s < dom.s_cross:  # start with lattice alpha(1) active
        ACT = 1
    elif s > dom.s_cross:  # start with lattice beta(-1) active
        ACT = -1
    else:  # randomise
        ACT = np.random.choice([-1, 1])

    # Flag for histogram flatness
    FLAT = 1  # start with 1 < f if wang-landau, otherwise f = 1 = FLAT

    # Initialise counters
    step = 1
    moves = 0
    retakes = 0
    switches = 0

    # ---------------------------- #
    #  Initialise 'dynamics' info  #
    # ---------------------------- #
    if track_dynamics == True:

        cuts = {'counter': 0, 'old_mu': old_mu, 'new_mu': old_mu}

        if TRAP == True:
            rt_min = 0
            rt_max = lendata - 1
        else:
            rt_min = np.argmax(binned_data['w'][mu_bins < 0])
            rt_max = np.argmax(binned_data['w'][mu_bins > 0]) + len(
                mu_bins[mu_bins < 0])

        rtrips = {
            'minmax': (0, rt_min, rt_max),
            'counts': 0,
            'flag': int(dyn_data['rt'][4])
        }

        # Mini transition matrix only works for TRAP == True (due to indexing)
        if TRAP == True:
            minimat = {
                'counter': 0,
                'root_index': old_index,
                'old_index': dyn.get_minibin_index(old_mu, s, old_index),
                'Pprod': 1
            }

    # --------------------------- #
    #  Open file for data series  #
    # --------------------------- #
    if track_series == True:
        series_file = alg.file_names('output', s, p)['s']
        series = open(series_file, 'a')

    # ------------------------------------------------------------ #
    #  Main loop over individual particle moves + switch attempts  #
    # ------------------------------------------------------------ #
    while FLAT < F or step <= Nsteps:  # Flat condition only relevant for Wang Landau

        # Refresh weights with eigenvector of transition matrix (TM only)
        if step % refresh_step == 0:
            alg.refresh_func(binned_data)

        # Write values from this step to the series file. Note high precision needed for mu
        if track_series == True:
            if step % series_step == 0:
                E_active = (0, old_E_alpha, old_E_beta)[ACT]
                series.write("%d %.10f %f %f \n" \
                        %(s, old_mu, old_weight, E_active) )

        # --------------------------------------------------- #
        #  Move a single particle and compute energy changes  #
        # --------------------------------------------------- #
        # Pick a random particle
        ipart = np.random.randint(0, Natoms)

        # Calculate old local energies for the two lattices before trial move
        old_local_energies = local_energy(atoms_alpha, atoms_beta, ipart)

        # Pick a random displacement and update lattice positions
        dr = (np.random.random(3) * 2.0 - 1.0) * dr_max
        dr_alpha = np.dot(dr, atoms_alpha.get_cell())
        dr_beta = np.dot(dr, atoms_beta.get_cell())
        atoms_alpha.positions[ipart, :] += dr_alpha
        atoms_beta.positions[ipart, :] += dr_beta

        # Calculate new local energies after trial move
        new_local_energies = local_energy(atoms_alpha, atoms_beta, ipart)

        # Calculate energy difference
        delta_local_energies = new_local_energies - old_local_energies

        # New energy difference between lattices
        if step % recalc_step == 1:  # full calculation
            new_E_alpha, new_E_beta = lattice_energies(atoms_alpha, atoms_beta)

            # Sanity check - don't want to be below ideal lattice energy!
            if new_E_alpha < E_ideal or new_E_beta < E_ideal:
                error(this_file,
                      "Oh no! Energy is less than that of an Ideal lattice.")

        else:  # update with local energy difference
            new_E_alpha = old_E_alpha + delta_local_energies[1]
            new_E_beta = old_E_beta + delta_local_energies[-1]

        new_mu = new_E_alpha - new_E_beta

        # ---------------- #
        #  Switch attempt  #
        # ---------------- #
        # Attempt a switch here 50% of the time - before any move evaluation
        coin = coinflip()
        ACT, switches = ((ACT, switches),
                         attempt_switch(new_mu, ACT, switches))[coin]

        # --------------------------------------- #
        #  Check if boundaries have been crossed  #
        # --------------------------------------- #
        # 'Global' boundaries are those that the simulation may not cross
        if new_mu < global_mu_min or new_mu > global_mu_max:

            # Update the bin from which the move was attempted
            old_weight, FLAT = alg.update_func(
                step,
                binned_data,
                delta_local_energies[ACT],
                old_index,
                old_index,
                old_index,  # only update edge bin
                old_mu,
                mu_bins,
                old_weight,
                get_weight,
                lendata,
                kTlogF,
                s)

            if track_dynamics == True:
                # Update data on simulation dynamics / mobility
                dyn.update_func(dyn_data, mu_bins, old_mu, old_index, s, cuts,
                                rtrips, False, abs(new_mu - old_mu),
                                abs(delta_local_energies[ACT]))

                if TRAP == True:
                    dyn.update_minimat(dyn_data, mu_bins, old_mu, old_index, s,
                                       minimat, True, 0)

            # Undo lattice positions update
            atoms_alpha.positions[ipart, :] -= dr_alpha
            atoms_beta.positions[ipart, :] -= dr_beta
            retakes += 1
            step += 1

            # Go back to the start of the while loop
            continue

        # Check if subdomain boundary crossed
        old_s = s
        if new_mu < dom.subdom[s]['min']:
            s -= 1
        elif new_mu > dom.subdom[s]['max']:
            s += 1

        # ---------------------- #
        #  Evaluate move result  #
        # ---------------------- #
        # Get index for arrays using mu
        new_index = get_index(new_mu, s)

        # Difference in weights augments delta_local_energy
        new_weight = get_weight(new_mu, new_index, mu_bins, binned_data['w'])
        augment = new_weight - old_weight

        # Accept/reject trial move with weighted energy difference
        expnt = -B * (delta_local_energies[ACT] + augment)
        accepted = accept_move(expnt)
        """ #Difference between bin-averaged weight and interpolated
        intra_bin_weight = old_weight - weights[old_index]
        #sampling_adjust = np.exp( B*intra_bin_weight ) # doesn't work: centre of bins?"""

        old_index_copy = old_index  # to update Cmat and extra info after move evaluation
        dmu = abs(new_mu - old_mu)  # to update dynamics

        # Update things according to whether move accepted
        if accepted == True:
            disp[ipart, :] += dr
            old_E_alpha = new_E_alpha
            old_E_beta = new_E_beta
            old_index = new_index
            old_weight = new_weight
            old_mu = new_mu
            moves += 1

            cuts_new_mu = new_mu

        else:
            atoms_alpha.positions[ipart, :] -= dr_alpha
            atoms_beta.positions[ipart, :] -= dr_beta
            s = old_s  # Account for possible subdomain change

            cuts_new_mu = old_mu

        # ------------------------ #
        #  Update bin information  #
        # ------------------------ #
        old_weight, FLAT = alg.update_func(step, binned_data,
                                           delta_local_energies[ACT],
                                           new_index, old_index,
                                           old_index_copy, old_mu, mu_bins,
                                           old_weight, get_weight, lendata,
                                           kTlogF, s)

        # ------------------------------------ #
        #  Update data on simulation dynamics  #
        # ------------------------------------ #
        if track_dynamics == True:

            # Update data on simulation dynamics / mobility
            cuts['new_mu'] = cuts_new_mu
            dyn.update_func(dyn_data, mu_bins, old_mu, old_index, s, cuts,
                            rtrips, accepted, dmu,
                            abs(delta_local_energies[ACT]))

            if TRAP == True:
                dyn.update_minimat(dyn_data, mu_bins, old_mu, old_index, s,
                                   minimat, accepted, expnt)

        # ---------------- #
        #  Switch attempt  #
        # ---------------- #
        # 50/50 chance of attempting a switch after the move
        ACT, switches = (attempt_switch(old_mu, ACT,
                                        switches), (ACT, switches))[coin]

        # ------------------- #
        #  Save periodically  #
        # ------------------- #
        if step % save_step == 0:
            alg.save_func(binned_data, mu_bins, step, s, p)

            # Take this opportunity to reset centre of mass
            atoms_alpha.positions = atoms_alpha.positions - atoms_alpha.get_center_of_mass(
            )
            atoms_beta.positions = atoms_beta.positions - atoms_beta.get_center_of_mass(
            )

        step += 1

    # End main loop

    print "- Steps: ", step
    print "- Moves: ", moves
    print "- Retakes: ", retakes
    print "- Switches: ", switches

    # --------------------------------------------- #
    #  Finalise things before returning to main.py  #
    # --------------------------------------------- #
    # Close series file
    if track_series == True:
        series.close()

    if track_dynamics == True:
        # Round trip output file
        dyn_data['rt'][0] += step
        dyn_data['rt'][1] += switches
        dyn_data['rt'][2] += rtrips['counts']  # half round trips
        rt_rate = float(0.5 * dyn_data['rt'][2] *
                        Natoms) / dyn_data['rt'][0]  # rtrips per sweep
        dyn_data['rt'][3] = 1.0 / rt_rate  # sweeps per rtrip
        dyn_data['rt'][4] = rtrips['flag']  # to be picked up by next iteration

    # Compute eigenvector and refresh weights
    alg.refresh_func(binned_data)

    # If interpolated weights used, remove those extrapolated bins / 'ghost points'
    if len(binned_data['w']) != len(binned_data['h']):
        binned_data['w'] = binned_data['w'][:-2]
        if track_dynamics == True:
            dyn_data['cu'] = dyn_data['cu'][:-2]

    # Only care about difference in weights, set minimum to zero
    binned_data['w'] -= np.min(binned_data['w'])

    return step
Пример #9
0
        data_comb = []


    # ------------------------------------------------------------ #
    #  Sum over processors operating in the same subdomain/domain  #
    # ------------------------------------------------------------ #
    for p in p_list[s::Ns_eff]:

        if TRAP == True:
            # Check correct mapping of processor to subdomain
            s_check = ini.map_proc_to_subdom(p)
            if s_check != s:
                error(this_file, "Mapping p -> s has gone wrong \nExpected p%d -> s%d, but got s%d" %(p,s_check,s))

        # Load files (output by main.py)
        input_file = alg.file_names('output', s, p)[argv[1]]
        this_data = np.loadtxt(input_file)
        
        # Add to sum
        if argv[1] in ('h', 'c'):
            data_comb = data_comb + this_data
        
        elif argv[1] == 's':
            ldc = len(data_comb)
            tmp = np.zeros( (ldc+len(this_data), 4) )
            if ldc > 0:
                tmp[:ldc,:] = data_comb
            tmp[ldc:,:] = this_data
            data_comb = tmp

Пример #10
0
import numpy as np
import matplotlib.pyplot as plt
from sys import argv, exit
from os.path import basename

from params import *

if algorithm == 'wang_landau': import wang_landau as alg
elif algorithm == 'multicanonical': import multicanonical as alg
elif algorithm == 'transition': import transition_matrix as alg

# Name of this file
this_file = basename(__file__)

deltaF_file = alg.file_names('dF')

# Can specify a non-default window size via argument variable
if len(argv) > 2:
    window = int(argv[2])

    # Can specify non-default data file
    if len(argv) > 3:
        deltaF_file = argv[3]

######################################################
## Functions to compute mean and standard deviation ##
######################################################
'''
########### Not convinced that this is working! ##########
def weighted_estimators(deltaF_series, error_series):