Beispiel #1
0
def mcmc_step(box, width, r_cut, r_skin, update_nblist):

    # kb = 1.38064852*10**(-13) # N*Å/K (Boltzmann constant)

    positions_trial = [np.zeros(box.dimension) for i in range(len(box.positions))]
    trial_step = width * np.random.randn(*np.asarray(positions_trial).shape)/4 #randn -> std norm. dist, divide by 4 to keep results mostly within (-0.5, 0.5)

    for i in range(len(positions_trial)):
        positions_trial[i] = pbc.enforce_pbc(box.positions[i] + trial_step[i], box.size) 
        
    particles_trial = [system.Particle(positions_trial[i], box.particles[i].charge, 
                                        box.particles[i].sigmaLJ, box.particles[i].epsilonLJ) for i in range(len(box.particles))] # set trial particle list with trial positions
    if update_nblist:
        particles_trial = neighbourlist.verlet_neighbourlist(particles_trial, r_cut, r_skin) # update neighbourlist for trial positions 
    else:
        for i in range(len(particles_trial)):
            particles_trial[i].neighbourlist = box.particles[i].neighbourlist 

    LJpotential_trial = lennardjones.LJ_potential(particles_trial, r_cut, r_skin)

    with warnings.catch_warnings():
        warnings.simplefilter("ignore")
        acceptance_prob = min(1.0, np.exp(-(LJpotential_trial - box.LJpotential)/box.temp)) # note: potential is actually potential/kb

    # if (box_trial.LJpotential>box.LJpotential):
    #     print("increase = " + repr(box_trial.LJpotential-box.LJpotential))
    #     print("acceptance prob. = " + repr(acceptance_prob))

    # if update_nblist:
    #     print(acceptance_prob)

    if np.random.rand() < acceptance_prob:
        return positions_trial, True, trial_step, acceptance_prob # Return True for accepted trial step return trial_step and acceptance_prob to use in unit testing
    return box.positions, False, trial_step, acceptance_prob # return False for rejected trial step (no need to update box object)
Beispiel #2
0
def mcmc_step(box, width, r_cut, r_skin, update_nblist, kb=0.008314462175):
    '''Executes single step of the MCMC simulation (see mcmc below).
    NB: Currently only using LJ potential. 
    
    Arguments:
        box (Box): the system/box object 
        width (float): approximate maximum size (change in individual coordinate) of each mcmc step
        r_cut (float): cut-off radius for LJ neighbourlist computation
        r_skin (float): size of skin-reigon for LJ neighbourlist computation
        kb (float): boltzmann constant. Default is given in kJ/(mol*K). Can be provided in different units if desired (will result in different units for the potential and distances...)
        
    Returns:
        box.positions (numpy array): the updated (if trial step was accepted) array of positions of the particles in the system
        _ (Bool): an unnamed boolean which relays whether or not the trial step was accepted
    '''

    positions_trial = np.zeros((len(box.particles), box.dimension))
    trial_step = width * np.random.randn(
        *positions_trial.shape
    ) / 4  #randn -> std norm. dist, divide by 4 to keep output mostly within (-0.5, 0.5)

    for i in range(len(positions_trial)):
        positions_trial[i] = pbc.enforce_pbc_coordinates(
            box.positions[i] + trial_step[i], box.size)

    if update_nblist:
        nblist_trial = neighbourlist.verlet_neighbourlist(
            positions_trial, r_cut, r_skin,
            box.size)  # update neighbourlist for trial positions
    else:
        nblist_trial = np.array(box.LJneighbourlists)

    LJpotential_trial = lennardjones.LJ_potential(positions_trial,
                                                  nblist_trial, box.sigmas,
                                                  box.epsilons, r_cut, r_skin,
                                                  box.size)

    with warnings.catch_warnings(
    ):  # suppress warnings for possibly large arguments of the exponential function
        warnings.simplefilter("ignore")
        acceptance_prob = min(
            1.0,
            np.exp(-(LJpotential_trial - box.LJpotential) / (kb * box.temp)))

    if np.random.rand() < acceptance_prob:
        return positions_trial, True  # Return True for accepted trial step
    return box.positions, False
Beispiel #3
0
def Ewald_energy(positions,q,r_c,r_s,boxsize):
    '''
    arguments:
        positions (numpy array): particles' positions
        q(numpy array): the chage value
        r_c (float): cutoff radius for Ewald
        r_s (float): cutoff radius for Ewald
        box(numpy array):the box length in each dimension
    '''
    r_cut = r_c + r_s    
    EWald_neighbourlists = neighbourlist.verlet_neighbourlist(positions, r_c, r_s, box)
    
    unit_convert = (1.602119892525e-19)**2/(4*np.pi*(10**(-10)))/(8.854187817e-12) /1000/128 * 6.022140857 * 10e23 #(kJ/mol)
    
    Ewald_short = Ewald_short_energy(positions,EWald_neighbourlists, q,r_cut,box) * unit_convert
    Ewald_long = Ewald_long_energy(positions,q,r_cut,box) * unit_convert
    Ewald_self = Ewald_self_energy(positions,q,r_cut) * unit_convert
    
    return Ewald_short + Ewald_long - Ewald_self
Beispiel #4
0
 def compute_LJneighbourlist(
     self, r_cut, r_skin
 ):  # computes the (LJ) neighbourlists for the particles in the system
     self.LJneighbourlists = neighbourlist.verlet_neighbourlist(
         self.positions, r_cut, r_skin, self.size)
Beispiel #5
0
    for i in range(len(positions)):
        Ewald_self += Ewald_self_energy_ij(q[i],r_cut)
    

    return Ewald_self


q = np.ones(128)
for i in range(128):
    if types[i] == 'Cl-' :
        q[i] = -1 #* 1.602119892525e-19
    else:
        q[i] = 1 #* 1.602119892525e-19

#pool = ThreadPoolExecutor(max_workers=2)
r_cut = min(box)/2
EWald_neighbourlists = neighbourlist.verlet_neighbourlist(positions, r_cut, 0, box) 
#print(EWald_neighbourlists)
unit_convert = (1.602119892525e-19)**2/(4*np.pi*(10**(-10)))/(8.854187817e-12) /1000/128 * 6.022140857 * 10e23

short = Ewald_short_energy(positions,EWald_neighbourlists, q, r_cut,box) * unit_convert
l = Ewald_long_energy(positions,q,r_cut,box) * unit_convert
s = Ewald_self_energy(positions,q,r_cut) * unit_convert
print("\rWith cutoff radius = half of the box length")
print("The Ewald short range energy:",short,"\t(kJ/mol)")
print("The Ewald long range energy:",l,"\t(kJ/mol)")
print("The Ewald self energy:",s ,"\t(kJ/mol)")
print("The total Ewald energy:",short+l-s,"(kJ/mol)")


Beispiel #6
0
 def compute_LJneighbourlist(self, r_cut, r_skin):
     self.particles = neighbourlist.verlet_neighbourlist(
         self.particles, r_cut, r_skin)