Can you review the following code to check to see if the Minimum Image Convention is properly implemented?
import random
import math
import matplotlib.pyplot as plt
polymer_chain_vec = []
N = 9
sigma = 2
epsilon = 2
periodic_boundary_int = 5 # size of the periodic box in A
temperature_float = 2 # temperature of the simulation
min_atom_distance_float = 1
max_atom_distance_float = 3.8
k = 1
sim_steps_int = 10000
write_steps_int = 10
def polymer_to_str():
return ' '.join([f'({round(point_pt[0], 2)},{round(point_pt[1], 2)})' for point_pt in polymer_chain_vec])
def plot_energies(energies):
plt.plot(range(len(energies)), energies)
plt.ylabel('E')
plt.xlabel('step')
plt.show()
def apply_boundary_condition(point_pt):
x, y = point_pt
x = x % periodic_boundary_int
y = y % periodic_boundary_int
return [x, y]
def get_distance(point_one_pt, point_two_pt):
dx = point_one_pt[0] - point_two_pt[0]
dy = point_one_pt[1] - point_two_pt[1]
dx -= periodic_boundary_int * round(dx / periodic_boundary_int)
dy -= periodic_boundary_int * round(dy / periodic_boundary_int)
return math.sqrt(dx**2 + dy**2)
def get_point_at_radius(current_point_pt, radius_double):
angle = random.random() * math.pi * 2
x = (math.cos(angle) * radius_double) + current_point_pt[0]
y = (math.sin(angle) * radius_double) + current_point_pt[1]
return apply_boundary_condition([x, y])
def morse_potential_func(r_float):
return math.exp(-2 * sigma * (r_float - min_atom_distance_float)) \
- 2 * math.exp(-sigma * (r_float - min_atom_distance_float))
def lj_energy_func(r_float):
return 4 * epsilon * ((sigma ** 12 / r_float ** 12) - (sigma ** 6 / r_float ** 6))
def harmonic_energy_func(r_float):
return k * ((r_float - max_atom_distance_float) ** 2)
def square_well_func(r_float):
d = r_float
en = 0
if d < min_atom_distance_float:
en += 10000000
elif d < max_atom_distance_float:
en += -1
return en
def get_potential(index_int):
bead_potential_float = 0
harmonic_potential_float = 0
current_loc_pt = polymer_chain_vec[index_int]
for i, other_loc_pt in enumerate(polymer_chain_vec):
if i != index_int:
r_float = get_distance(current_loc_pt, other_loc_pt)
bead_potential_float += morse_potential_func(r_float)
if index_int >= 1: # 1....8
r_float = get_distance(current_loc_pt, polymer_chain_vec[index_int - 1])
harmonic_potential_float += harmonic_energy_func(r_float)
if index_int < len(polymer_chain_vec) - 1: # 0....7
r_float = get_distance(current_loc_pt, polymer_chain_vec[index_int + 1])
harmonic_potential_float += harmonic_energy_func(r_float)
return bead_potential_float + harmonic_potential_float
def get_total_potential():
harmonic_float = 0
pair_float = 0
for i in range(len(polymer_chain_vec) - 1):
bead_i = polymer_chain_vec[i]
bead_i_plus_1 = polymer_chain_vec[i + 1]
r_float = get_distance(bead_i, bead_i_plus_1)
harmonic_float += harmonic_energy_func(r_float)
for j in range(i + 1, len(polymer_chain_vec), 1):
bead_j = polymer_chain_vec[j]
r_float = get_distance(bead_i, bead_j)
pair_float += morse_potential_func(r_float)
return harmonic_float + pair_float
def initialize_polymer():
current_point_pt = [0, 0]
polymer_chain_vec.append(current_point_pt)
for _ in range(N - 1):
new_loc_pt = get_point_at_radius(current_point_pt, max_atom_distance_float)
polymer_chain_vec.append(new_loc_pt)
current_point_pt = new_loc_pt
def run_simulation(steps_int):
for _ in range(steps_int):
rand_index_int = random.randint(0, len(polymer_chain_vec) - 1)
before_loc_pt = polymer_chain_vec[rand_index_int]
before_pot_float = get_potential(rand_index_int)
new_loc_pt = get_point_at_radius(before_loc_pt, max_atom_distance_float)
polymer_chain_vec[rand_index_int] = new_loc_pt
after_pot_float = get_potential(rand_index_int)
pot_diff_float = after_pot_float - before_pot_float
if pot_diff_float < 0:
pass
else:
rand_float = random.random()
if math.exp(-pot_diff_float / temperature_float) > rand_float:
pass
else:
polymer_chain_vec[rand_index_int] = before_loc_pt
if __name__ == '__main__':
initialize_polymer()
total_pot_vec = []
for ii in range(1, sim_steps_int, 1):
run_simulation(write_steps_int)
total_pot_double = round(get_total_potential())
total_pot_vec.append(total_pot_double)
plt.plot(range(len(total_pot_vec)), total_pot_vec)
plt.show()