def get_energy_edges(self): """ Evaluate what minimum and maximum energies are for wang-landau sampling and split into bins where no bin has a zero count """ energy_store = [] N = 10000 ii = 0 z1 = copy.deepcopy(self) while ii < N: z2, r1, r2 = MC.IonMove(z1) delG = MC.Energy_Difference(z1, z2, r1, r2) z2.energy += delG energy_store.append(z2.energy) z1 = copy.deepcopy(z2) del (z2) ii += 1 # Find unique values and then keep reducing bin size until all bins have at least one count tmp1 = list(set(energy_store)) bins = 80 tmp2 = np.histogram(tmp1, bins=bins) while 0 in tmp2[0]: bins -= 1 tmp2 = np.histogram(tmp1, bins=bins) print("# of bins: ", bins) self.energy_edges = tmp2[1] return tmp1
def wang_landau(self): """ Perform wang_landau simulation Arguments: self {class} -- Lattice class """ # Possible energies energy_edges = self.energy_edges energy_edges = energy_edges[:-1] energy_store = [] hist = np.zeros(len(energy_edges)) entropy = np.zeros(len(energy_edges)) ln_factor = 1 ii = 1 while ln_factor > 1e-3 and ii < 80000: # Perform Monte Carlo Move on lattice z1, r1, r2 = MC.IonMove(self) delG = MC.Energy_Difference(self, z1, r1, r2) z1.energy += delG energy_store.append(z1.energy) new_edge = np.digitize(z1.energy, energy_edges) - 1 old_edge = np.digitize(self.energy, energy_edges) - 1 P = np.exp(entropy[old_edge] - entropy[new_edge]) if P > np.random.rand(): old_edge = new_edge self = copy.deepcopy(z1) entropy[old_edge] += ln_factor hist[old_edge] += 1 del (z1) if is_flat(hist): hist[:] = 0 ln_factor /= 2 print(ln_factor, ii) ii += 1 print("ln(f): ", ln_factor, "iter #: ", ii) return hist, entropy, energy_store