def myDiscreteRandom3(): if belongs(random(), 0, 0.3333): return 1 elif belongs(random(), 0.3333, 0.6666): return 2 else: return 3
def move3(cfg, nSteps, Emin, Em, Emplus1, L): hasMoved = False acceptances = 0 [I_EminToEm, I_EmToEmplus1, I_Emplus1ToInfty] = [0, 0, 0] Eold = model.getEnergy(cfg) for i in range(nSteps): # iAtom, idim, l = s(6, L) if hasMoved: hasMoved = False Eold = e # cfgTemp = getMove3(cfg) e = model.getEnergy(cfgTemp) if (e <= Emplus1): hasMoved = True cfg = copy.deepcopy(cfgTemp) acceptances += 1 # accepted move. draw(cfg.positions, e) cfg.translate(-cfg.get_center_of_mass()) else: e = Eold # if belongs( e, Emin, Em ): # (Emin <= e <= E[m - 1]): #<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< I_EminToEm += 1 # un gol más para ∫_Emin^Em-1 Ω(E)dE elif belongs(e, Em, Emplus1): # (E[m - 1] <= e <= Em): I_EmToEmplus1 += 1 # un gol más para ∫_Em-1^Em Ω(E)dE elif Emplus1 < e: I_Emplus1ToInfty += 1 # # ratioAcceptances = float( acceptances ) / nSteps #`float()` to ensure the division will be a float (python2 resembles Fortran in divisions) if I_EminToEm == 0: I_EminToEm = 1 alpha = I_EmToEmplus1 / float( I_EminToEm ) # `float()` to ensure the division will be a float (python2 resembles Fortran in divisions) print("alpha = ", float("{0:.3f}".format(alpha))) print(float("{0:.3f}".format(ratioAcceptances)), I_EminToEm, I_EmToEmplus1, I_Emplus1ToInfty, "...", L) return alpha, ratioAcceptances
def move(X, sigma, epsilon, rcut, nSteps, Emin, Em, Emplus1, L): hasMoved = False acceptances = 0 [I_EminToEm, I_EmToEmplus1, I_Emplus1ToInfty] = [0, 0, 0] Eold = cf.getLJenergy(X, sigma, epsilon) # acceptances # I_EminToEm # I_EmToEmplus1 for i in range(nSteps): # iAtom = i % len(X) # iAtom = int(random() * len(X)) # idim = int(random() * 6) # get a configuration e,X after randomly move X: # Eold = getEnergyConfig(X) # assert( Eo == getEnergyConfig(X) ) iAtom, idim, l = s(6, L) if hasMoved: hasMoved = False Eold = e # # Xt = copy.deepcopy(X) # d = Vector3(getRandomWalk(L), getRandomWalk(L), getRandomWalk(L)) # d = unitVect(idim) * getRandomWalk(L) d = unitVect2(idim) * L * (random() - 0.5) # d = unitVect2(idim) * l ######################################################################## Xt[iAtom] += d ######################################################################## ######################################################################## # getForceMatrix = False # if use_mtp: e, eigenvalues = cf.getLJeigenvalues2(Xt, epsilon, sigma, rcut, getForceMatrix, aCell) elif use_aseLJ: e, eigenvalues = cf.getLJeigenvalues(Xt, epsilon, sigma, rcut, getForceMatrix) # # e = cf.getLJenergy(Xt, sigma, epsilon) # P_old2new = mc.getProbTransition(e, Eold, Em, EmMinus1) # P_old2new = mc.getProbTransition(e, Eold, Emplus1 + 0.0004, Em) # P_old2new = mc.getProbTransition(e, Eold, Emplus1, Em) # os.system("echo "+ str(e) + " >> out2.txt") # if (e <= Emplus1 + 0.001): # if (e <= Emplus1 + 0.0006): # if (e <= Emplus1 + 0.0002): if (e <= Emplus1): # if ( P_old2new >= random() ): # os.system("echo "+ str(e) + " >> out.txt") hasMoved = True # X = copy.deepcopy(Xt) X[iAtom] += d acceptances += 1 # accepted move. draw(X, e) X = maintainCenterOfMass(X) else: e = Eold # # # it has no sense to add the same configuration (not moved) to Ω: # if hasMoved: # acceptances += 1 # accepted move. # # if belongs( e, Emin, Em ): # (Emin <= e <= E[m - 1]): #<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< I_EminToEm += 1 # un gol más para ∫_Emin^Em-1 Ω(E)dE elif belongs(e, Em, Emplus1): # (E[m - 1] <= e <= Em): I_EmToEmplus1 += 1 # un gol más para ∫_Em-1^Em Ω(E)dE elif Emplus1 < e: I_Emplus1ToInfty += 1 # # ratioAcceptances = float( acceptances ) / nSteps #`float()` to ensure the division will be a float (python2 resembles Fortran in divisions) if I_EminToEm == 0: I_EminToEm = 1 alpha = I_EmToEmplus1 / float( I_EminToEm ) # `float()` to ensure the division will be a float (python2 resembles Fortran in divisions) print("alpha = ", float("{0:.3f}".format(alpha))) print(float("{0:.3f}".format(ratioAcceptances)), I_EminToEm, I_EmToEmplus1, I_Emplus1ToInfty, "...", L) # acceptances # I_EminToEm # I_EmToEmplus1 ################################################################################ # log_idos.append( log_sum_idos + log(alpha) ) # =log_idos[m] # # # calculate log_sum_idos: # # Log of the sum of integrals for each interval, m=1, m=2, m=3,... # DOSintegrals = [ exp(log_int) for log_int in log_idos ] # log_sum_idos = log(sum(DOSintegrals)) # # return alpha, log_idos, log_sum_idos, L # return alpha return alpha, ratioAcceptances
def move2(X, sigma, epsilon, rcut, nSteps, Emin, Em, Emplus1, L): hasMoved = False acceptances = 0 [I_EminToEm, I_EmToEmplus1, I_Emplus1ToInfty] = [0, 0, 0] Eold = cf.getLJenergy(X, sigma, epsilon) for i in range(nSteps): # iAtom, idim, l = s(6, L) if hasMoved: hasMoved = False Eold = e # # d = unitVect2(idim) * L * (random() - 0.5) ######################################################################## Xt, St = getMove(nAtoms, X, canSwap, neighbors, S) #move includes translation or swap # Xt[iAtom] += d ######################################################################## ######################################################################## # getForceMatrix = False # if use_mtp: e, eigenvalues = cf.getLJeigenvalues2B(Xt, St, epsilon, sigma, rcut, getForceMatrix, aCell) elif use_aseLJ: e, eigenvalues = cf.getLJeigenvaluesB(Xt, St, epsilon, sigma, rcut, getForceMatrix) # if (e <= Emplus1): hasMoved = True # X = copy.deepcopy(Xt) # X[iAtom] += d # X = copy.deepcopy(Xt) # S = copy.deepcopy(St) X = Xt # ??????????????????????????????????????????????????????????? S = St acceptances += 1 # accepted move. draw(X, e) X = maintainCenterOfMass(X) else: e = Eold # # if belongs( e, Emin, Em ): # (Emin <= e <= E[m - 1]): #<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< I_EminToEm += 1 # un gol más para ∫_Emin^Em-1 Ω(E)dE elif belongs(e, Em, Emplus1): # (E[m - 1] <= e <= Em): I_EmToEmplus1 += 1 # un gol más para ∫_Em-1^Em Ω(E)dE elif Emplus1 < e: I_Emplus1ToInfty += 1 # # ratioAcceptances = float( acceptances ) / nSteps #`float()` to ensure the division will be a float (python2 resembles Fortran in divisions) if I_EminToEm == 0: I_EminToEm = 1 alpha = I_EmToEmplus1 / float( I_EminToEm ) # `float()` to ensure the division will be a float (python2 resembles Fortran in divisions) print("alpha = ", float("{0:.3f}".format(alpha))) print(float("{0:.3f}".format(ratioAcceptances)), I_EminToEm, I_EmToEmplus1, I_Emplus1ToInfty, "...", L) return alpha, ratioAcceptances
def randomMCmovesParallel2(Eminimo, E_mMinus2, E_mMinus1, E_m,\ nSteps, e, X, L, structEq, Xeq, forceMatrix): import copy import harmonic as ha print("Emin, E_m2, E_m1, E_m = ", Eminimo, E_mMinus2, E_mMinus1, E_m) lCfgs = [] # to save cfgs for the next subdivision. # where: lCfgs_m = [cfg_1, cfg_2, ..., cfg_i, ...] # where: cfg_i = [energy_i, X_i ] # where: cfg_i = [energy_i, X_i ] # where: X_i = [r1, r2, r3, r4, ..., rNatoms] # where: r_n = [x,y,z] #=========================================================================== # paper: "The maximum displacement of the translational moves is # automatically changed after each partitioning process to adjust the # acceptance toward the range 25%–35%. If the acceptance rate during a # partitioning process falls below 10% or above 70%, the partitioning # process is repeated." # L ~amplitud of random walk of a ... # ...particle (dx,dy,dz) = (L*random(), L*random(), L*random()) ratioOfCfgsToSave = 0.5 ratioAcceptances = 0 # L = 0.1 repMax = 1 #10 # maximum number of repetitions to get the appropriate ratio of # acceptances at a certain L value. repeat = 0 ratioMin = 0.25 ratioMax = 0.35 while( (not belongs(ratioAcceptances, ratioMin, ratioMax) and\ (repeat < repMax) ) or\ continuar): continuar = False [I1, I2] = [0, 0] repeat += 1 acceptances = 0 # Collect ehist for [Emin,E[m-1]] and [E[m-1],Em]: for i in range(nSteps): # get a configuration e,X after randomly move X: e, X, hasMoved = mc_move(i, e, X, Xeq, forceMatrix, E_mMinus1, E_mMinus2, L, structEq) # it has no sense to add the same configuration (not moved) to Ω: if hasMoved: acceptances += 1 # accepted move. if belongs(e, E_mMinus1, E_m): # (E[m - 1] <= e <= Em): I1 += 1 # un gol más para ∫_Em-1^Em Ω(E)dE elif belongs(e, Eminimo, E_mMinus1): # (Emin <= e <= E[m - 1]): #<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< # elif belongs(e, E_mMinus1 - 10, E_mMinus1): # (Emin <= e <= E[m - 1]): I2 += 1 # un gol más para ∫_Emin^Em-1 Ω(E)dE # # randomly save some configs to use for the next subdivision: # if random() > ratioOfCfgsToSave: lCfgs.append([e, X]) if random.random() > ratioOfCfgsToSave: lCfgs.append([e, X]) # if (e < 1.1 * Eminimo): print(e, Eminimo) ######################################################################################## import os c = counter() nAtoms = len(X) # out = "/Users/chinchay/Documents/9_Git/reverseEnergyPartitioning/ovitoPlots/moves." + str(c) + ".xyz" out = "ovitoPlots/moves." + str(c) + ".xyz" pos = str(nAtoms) + "\n\n" for i in range(len(X)): pos += "H " + str(X[i][0]) + " " + str(X[i][1]) + str(X[i][2]) + "\n" # pos += "\n" f = open(out, "w") f.write(pos) f.close() ######################################################################################## assert (1 == 0) # print(I1, I2, e, hasMoved, belongs(e, E_mMinus1 - 10, E_mMinus1), belongs(e, Eminimo, E_mMinus1), belongs(e,E_mMinus1, E_m), L) # ratioAcceptances = acceptances / nSteps print(ratioAcceptances, I2, I1, e, E_mMinus1, E_m, belongs(e, Eminimo, E_mMinus1), belongs(e,E_mMinus1, E_m), L, repeat) factor = (I1 + 1) / (I2 + 1) # '+1' to avoid zeros assert( len(lCfgs) != 0 ) minVal = 10 if ( (I1 < minVal) and (I2 < minVal)): # choose X with lower energy print("A: choosing config with min energy ...") nthMin = 1 e, X = select_start_config(lCfgs, E_mMinus1, E_m, nthMin) continuar = True elif factor < 1/100.0: # choose X with higher energy print("B: choosing config with high energy ...") nthMin = 2 e, X = select_start_config(lCfgs, E_mMinus1, E_m, nthMin) continuar = True elif factor > 100: # choose X with lower energy print("C: choosing config with min energy ...") nthMin = 1 e, X = select_start_config(lCfgs, E_mMinus1, E_m, nthMin) continuar = True # # # # calculate α_m, log_idos: # alpha = I1 / I2 # MonteCarlo: ~cociente de goles ∫_Em-1^Em / ∫_Emin^Em-1 # assert(alpha != 0) # print(alpha, L) # log_idos.append( log_sum_idos + log(alpha) ) # =log_idos[m] # # # calculate log_sum_idos: # # Log of the sum of integrals for each interval, m=1, m=2, m=3,... # DOSintegrals = [ exp(log_int) for log_int in log_idos ] # log_sum_idos = log(sum(DOSintegrals)) # output.put( (I1, I2, lCfgs) ) # output.put( (lCfgs, alpha, log_idos, log_sum_idos, L) ) # return lCfgs, alpha, log_idos, log_sum_idos, L return I1, I2, lCfgs
def randomMCmoves(Eminimo, E_mMinus1, E_m, E_mplus1,\ nSteps, e, X, log_idos, log_sum_idos, L): import copy import os # import harmonic as ha Eo = getEnergyConfig(X) Xo = copy.deepcopy(X) lCfgs = [] # to save cfgs for the next subdivision. # where: lCfgs_m = [cfg_1, cfg_2, ..., cfg_i, ...] # where: cfg_i = [energy_i, X_i ] # where: cfg_i = [energy_i, X_i ] # where: X_i = [r1, r2, r3, r4, ..., rNatoms] # where: r_n = [x,y,z] #=========================================================================== # paper: "The maximum displacement of the translational moves is # automatically changed after each partitioning process to adjust the # acceptance toward the range 25%–35%. If the acceptance rate during a # partitioning process falls below 10% or above 70%, the partitioning # process is repeated." # L ~amplitud of random walk of a ... # ...particle (dx,dy,dz) = (L*random(), L*random(), L*random()) ratioOfCfgsToSave = 0.5 ratioAcceptances = 0 # L = 0.1 repMax = 10 #10 # maximum number of repetitions to get the appropriate ratio of # acceptances at a certain L value. repeat = 0 ratioMin = 0.25 ratioMax = 0.35 while( (not belongs(ratioAcceptances, ratioMin, ratioMax) and\ (repeat < repMax) ) or\ continuar): # print(condition1, condition2, continuar, finalCondition) continuar = False # Reset energy histogram: ehist = [I1, I2]. # I1 = c*∫_Em-1^Em Ω(E)dE; I2 = c*∫_Emin^Em-1 Ω(E)dE, `c` is some constant. if (repeat > 0): # if I2 == 0: # repeat = 0 # # L = 0.99 * L if ratioAcceptances > ratioMax: L = 1.1 * L print("...... increasing L = ", float("{0:.3f}".format(L)), repeat, ratioAcceptances) X = copy.deepcopy(Xo) return 0 elif ratioAcceptances < ratioMin: L = 0.9 * L print("...... decreasing L = ", float("{0:.3f}".format(L)), repeat, ratioAcceptances) X = copy.deepcopy(Xo) return 0 # [I_EminToEm, I_EmToEmplus1, I_Emplus1ToInfty] = [0, 0, 0] repeat += 1 acceptances = 0 # L = L * 0.8 # Decrease the amplitud of the random walk to get the # desired ratioAcceptances range values [25%, 35%]. # You can improve with a more sophisticated algorithm here. # Collect ehist for [Emin,E[m-1]] and [E[m-1],Em]: for i in range(nSteps): # get a configuration e,X after randomly move X: Eold = getEnergyConfig(X) # assert( Eo == getEnergyConfig(X) ) hasMoved = False Xtemp = copy.deepcopy(X) Xtemp = getNewConfig(i, Xtemp, L) Enew = getEnergyConfig(Xtemp) # P_old2new = getProbTransition(E_new, E_old, E_m, E_m_minus_1) # P_old2new = getProbTransition(Enew, Eold, E_mplus1, E_m) os.system("echo " + str(Enew) + " >> out2.txt") # if (Enew <= E_mplus1 + 0.001): if (Enew <= E_mplus1 + 0.0006): # if ( P_old2new >= random() ): os.system("echo " + str(Enew) + " >> out.txt") hasMoved = True e = Enew X = copy.deepcopy(Xtemp) # # hasMoved = True # e = Enew # X = copy.deepcopy(Xtemp) # e, X, hasMoved = mc_move(i, e, X, E_mplus1, E_m, E_mMinus1, L) # # Xo = copy.deepcopy(X) # # assert(id(Xo) != id(X)) # # e, Xtemporal, hasMoved = mc_move(i, e, Xo, Xeq, forceMatrix, E_mMinus1, E_mMinus2, L, a1, a2, a3) # # # assert(id(Xo) != id(Xtemporal)) # # if (hasMoved == False): # # for k in range(len(Xo)): # # for l in range(3) : # # assert(Xo[k][l] == Xtemporal[k][l]) # # # # # X = copy.deepcopy(Xtemporal) # # # c = counter() # rHyper, deltaEharmonic = ha.getHarmonicEnergy(X, Xeq, forceMatrix) # out = "/Users/chinchay/Documents/9_Git/reverseEnergyPartitioning/ovitoPlots/rHyperEHarmonic" + str(c) + ".txt" # # s = str(rHyper) + " , " + str(deltaEharmonic) + " , " + str(E_new) + "\n" # s = str(rHyper) + " , " + str(deltaEharmonic) + "\n" # f = open(out, "w") # f.write(s) # f.close() # it has no sense to add the same configuration (not moved) to Ω: if hasMoved: acceptances += 1 # accepted move. if belongs( e, Eminimo, E_m ): # (Emin <= e <= E[m - 1]): #<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< I_EminToEm += 1 # un gol más para ∫_Emin^Em-1 Ω(E)dE elif belongs(e, E_m, E_mplus1): # (E[m - 1] <= e <= Em): I_EmToEmplus1 += 1 # un gol más para ∫_Em-1^Em Ω(E)dE elif E_mplus1 < e: I_Emplus1ToInfty += 1 # # randomly save some configs to use for the next subdivision: if random() > ratioOfCfgsToSave: lCfgs.append([e, X]) # if (e < 1.1 * Eminimo): print(e, Eminimo) ######################################################################################## import os c = counter() nAtoms = len(X) out = "/Users/chinchay/Documents/9_Git/reverseEnergyPartitioning/ovitoPlots/moves." + str( c) + ".xyz" pos = str(nAtoms) + "\n\n" for i in range(len(X)): pos += "H " + str(X[i][0]) + " " + str(X[i][1]) + str( X[i][2]) + "\n" # pos += "\n" f = open(out, "w") f.write(pos) f.close() ######################################################################################## assert (1 == 0) # print(I1, I2, e, hasMoved, belongs(e, E_mMinus1 - 10, E_mMinus1), belongs(e, Eminimo, E_mMinus1), belongs(e,E_mMinus1, E_m), L) # ratioAcceptances = acceptances / nSteps # print(ratioAcceptances, I_EminToEm, I_EmToEmplus1, e, E_m, E_mplus1, belongs(e, Eminimo, E_m), belongs(e,E_m, E_mplus1), L, repeat) # print(ratioAcceptances, I_EminToEm, I_EmToEmplus1, I_Emplus1ToInfty, L, repeat) f = (I_EminToEm + I_EmToEmplus1) / (I_EminToEm + I_EmToEmplus1 + I_Emplus1ToInfty) ff = I_EmToEmplus1 / (I_EmToEmplus1 + I_Emplus1ToInfty) print(float("{0:.3f}".format(ratioAcceptances)), I_EminToEm, I_EmToEmplus1, I_Emplus1ToInfty, "...", float("{0:.3f}".format(f)), float("{0:.3f}".format(ff)), L, repeat, Eo) factor = (I_EmToEmplus1 + 1) / (I_EminToEm + 1) # '+1' to avoid zeros assert (len(lCfgs) != 0) # if ( (I_EmToEmplus1 < 100) or (I_EminToEm < 100)): # # choose X with lower energy # print("A: choosing config with min energy ...") # nthMin = 1 # e, X = select_start_config(lCfgs, E_mMinus1, E_m, nthMin) # continuar = True if factor < 1 / 100.0: # # choose X with higher energy print("B: choosing config with high energy ...") # nthMin = 2 # e, X = select_start_config(lCfgs, E_mMinus1, E_m, nthMin) L = 1.1 * L continuar = True elif factor > 100: # choose X with lower energy print("C: choosing config with min energy ...") # nthMin = 1 # e, X = select_start_config(lCfgs, E_mMinus1, E_m, nthMin) L = 0.9 * L continuar = True # # if ( (I1 < 100) or (I2 < 100)): # assert( len(lCfgs) != 0 ) # print("choosing config with min energy ...") # nthMin = 1 # e, X = select_start_config(lCfgs, E_mMinus1, E_m, nthMin) # c = counterMin() # if (c % 3 == 2): # print("choosing back ...") # nthMin = 3 # e, X = select_start_config(lCfgs, E_mMinus1, E_m, nthMin) # # # # if (c % 5 == 4): # # print("increasing nSteps ...") # # nSteps = nSteps * 2 # # # continuar = True # if (not belongs(ratioAcceptances, ratioMin, ratioMax)): # assert( len(lCfgs) != 0 ) # # print("choosing config with max energy ...") # # print("increasing L value ...") # # nthMin = 2 # # e, Xtemp = select_start_config(lCfgs, E_mMinus1, E_m, nthMin) # # X = copy.deepcopy(Xtemp) # # nthMin = 1 # e, X = select_start_config(lCfgs, E_mMinus1, E_m, nthMin) # continuar = True # # if ratioAcceptances <= ratioMin: # print("decreasing L value ...") # L = L / 1.2 # elif ratioMax <= ratioAcceptances: # print("increasing L value ...") # L = L * 1.2 # # continuar = True #=========================================================================== # calculate α_m, log_idos: alpha = I_EmToEmplus1 / I_EminToEm # MonteCarlo: ~cociente de goles ∫_Em-1^Em / ∫_Emin^Em-1 assert (alpha != 0) print("....................................alpha = " + str(float("{0:.3f}".format(alpha))) + " L = " + str(float("{0:.3f}".format(L)))) log_idos.append(log_sum_idos + log(alpha)) # =log_idos[m] # calculate log_sum_idos: # Log of the sum of integrals for each interval, m=1, m=2, m=3,... DOSintegrals = [exp(log_int) for log_int in log_idos] log_sum_idos = log(sum(DOSintegrals)) return lCfgs, alpha, log_idos, log_sum_idos, L