Skip to content

Commit 709f159

Browse files
committed
Update examples
1 parent b5df1ef commit 709f159

39 files changed

Lines changed: 35169 additions & 934 deletions

example/data/MoS2_vasp.xyz

Lines changed: 1608 additions & 0 deletions
Large diffs are not rendered by default.

example/data/Si-Ge_interfaces_vasp.xyz

Lines changed: 29450 additions & 0 deletions
Large diffs are not rendered by default.

example/python_pkg/Al_learn/DRAFFLE/learn.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ def process_structure(i, atoms, num_structures_old, calc_params, optimise_struct
126126
unrlxd_structures = []
127127
rlxd_structures = []
128128
iter2 = 0
129+
generator.init_seed(seed)
129130
# start the iterations, loop over the hosts, then repeat the process X times
130131
for iter in range(10):
131132
for host in hosts:
@@ -144,8 +145,7 @@ def process_structure(i, atoms, num_structures_old, calc_params, optimise_struct
144145
generator.generate(
145146
num_structures = 5,
146147
stoichiometry = { 'Al': num_atoms },
147-
seed = seed*1000+iter,
148-
method_ratio = {"void": 0.5, "rand": 0.001, "walk": 0.5, "grow": 0.0, "min": 1.0},
148+
method_ratio = {"void": 0.1, "rand": 0.01, "walk": 0.25, "grow": 0.25, "min": 1.0},
149149
verbose = 0,
150150
)
151151

example/python_pkg/Al_learn/DRAFFLE/learn_placement.py

Lines changed: 92 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
# from mace.calculators import mace_mp
22
# from ase.calculators.vasp import Vasp
33
from chgnet.model import CHGNetCalculator
4+
from ase.calculators.singlepoint import SinglePointCalculator
45
from raffle.generator import raffle_generator
56
from ase import build, Atoms
6-
from ase.optimize import BFGS, FIRE
7+
from ase.optimize import FIRE
78
from ase.io import write
89
from ase.visualize import view
910
import numpy as np
@@ -31,17 +32,10 @@ def runInParallel(*fns):
3132
print(results)
3233

3334

34-
def process_structure_with_queue(i, structure, num_old, calc_params, optimise_structure, iteration, queue):
35-
# Perform the computation
36-
result = process_structure(i, structure, num_old, calc_params, optimise_structure, iteration)
37-
queue.put(result) # Report completion
38-
39-
def process_structure(i, atoms, num_structures_old, calc_params, optimise_structure, iteration):
40-
if i < num_structures_old:
41-
return
35+
def process_structure(i, atoms, calc_params, optimise_structure, calc):
36+
# Check if the structure has already been processed
4237

4338
# calc = Vasp(**calc_params, label=f"struct{i}", directory=f"iteration{iteration}/struct{i}/", txt=f"stdout{i}.o")
44-
inew = i - num_structures_old
4539
atoms.calc = calc
4640
# positions_initial = atoms.get_positions()
4741

@@ -51,7 +45,7 @@ def process_structure(i, atoms, num_structures_old, calc_params, optimise_struct
5145

5246
# Optimise the structure if requested
5347
if optimise_structure:
54-
optimizer = FIRE(atoms, trajectory = f"traje{inew}.traj", logfile=f"optimisation{inew}.log")
48+
optimizer = FIRE(atoms, trajectory = f"traje{i}.traj", logfile=f"optimisation{i}.log")
5549
try:
5650
optimizer.run(fmax=0.05, steps=100)
5751
except Exception as e:
@@ -72,7 +66,7 @@ def process_structure(i, atoms, num_structures_old, calc_params, optimise_struct
7266
print(f"Distance too small: {atoms.get_all_distances(mic=True).min()}")
7367
return None, None, None
7468

75-
if abs(energy_rlxd - energy_unrlxd) > 10.0:
69+
if abs(energy_rlxd - energy_unrlxd) > 5.0:
7670
print(f"Energy difference too large: {energy_rlxd} vs {energy_unrlxd}")
7771
return None, None, None
7872

@@ -137,9 +131,17 @@ def process_structure(i, atoms, num_structures_old, calc_params, optimise_struct
137131
"""
138132
#void_val; rand_val; walk_val; grow_val; min_val
139133
##############[ V, R, W, G, M]
140-
method_val = [85.0, 15.0, 0.0, 0.0, 0.0] #change
141-
142-
134+
method_dicts = [
135+
{"void": 1.0, "rand": 0.0, "walk": 0.0, "grow": 0.0, "min": 0.0},
136+
{"void": 0.0, "rand": 1.0, "walk": 0.0, "grow": 0.0, "min": 0.0},
137+
{"void": 0.0, "rand": 0.0, "walk": 1.0, "grow": 0.0, "min": 0.0},
138+
{"void": 0.0, "rand": 0.0, "walk": 0.0, "grow": 1.0, "min": 0.0},
139+
{"void": 0.0, "rand": 0.0, "walk": 0.0, "grow": 0.0, "min": 1.0},
140+
{"void": 85.0, "rand": 15.0, "walk": 0.0, "grow": 0.0, "min": 0.0},
141+
{"void": 0.0, "rand": 15.0, "walk": 85.0, "grow": 0.0, "min": 0.0},
142+
{"void": 0.0, "rand": 15.0, "walk": 0.0, "grow": 85.0, "min": 0.0},
143+
{"void": 0.0, "rand": 15.0, "walk": 0.0, "grow": 0.0, "min": 85.0},
144+
]
143145

144146
hosts = []
145147
for crystal_structure in crystal_structures:
@@ -166,8 +168,26 @@ def process_structure(i, atoms, num_structures_old, calc_params, optimise_struct
166168
density = 1.61 # u/A^3
167169
# num_atoms = 7
168170

169-
for seed in range(1):
170-
print(f"Seed: {seed}")
171+
# get the current directory
172+
cwd = os.getcwd()
173+
print(f"Current working directory: {cwd}")
174+
175+
seed = 0
176+
for methods in method_dicts:
177+
# move to the cwd
178+
os.chdir(cwd)
179+
print(f"Changed directory to {cwd}")
180+
181+
# print the methods
182+
print(f"Method: {methods}")
183+
184+
# make method directory
185+
method_dir = f"method_v{methods['void']}_r{methods['rand']}_w{methods['walk']}_g{methods['grow']}_m{methods['min']}/"
186+
if not os.path.exists(method_dir):
187+
os.makedirs(method_dir)
188+
os.chdir(method_dir)
189+
print(f"Changed directory to {method_dir}")
190+
171191
energies_rlxd_filename = f"energies_rlxd_seed{seed}.txt"
172192
energies_unrlxd_filename = f"energies_unrlxd_seed{seed}.txt"
173193
generator = raffle_generator()
@@ -198,11 +218,17 @@ def process_structure(i, atoms, num_structures_old, calc_params, optimise_struct
198218
else:
199219
open(energies_unrlxd_filename, "w").close()
200220

221+
# delete .traj files if they exist
222+
if os.path.exists(f"unrlxd_structures_seed{seed}.xyz"):
223+
os.remove(f"unrlxd_structures_seed{seed}.xyz")
224+
if os.path.exists(f"rlxd_structures_seed{seed}.xyz"):
225+
os.remove(f"rlxd_structures_seed{seed}.xyz")
201226

202-
num_structures_old = 0
227+
num_structures_tot = 0
203228
unrlxd_structures = []
204229
rlxd_structures = []
205-
iter2 = 0
230+
iter2 = -1
231+
generator.init_seed(put=seed)
206232
for iter in range(10):
207233
for host in hosts:
208234
generator.set_host(host)
@@ -215,17 +241,16 @@ def process_structure(i, atoms, num_structures_old, calc_params, optimise_struct
215241
print(f"Volume: {volume}")
216242
print(f"Number of atoms: {num_atoms}")
217243

218-
generator.generate(
244+
generated_structures = generator.generate(
219245
num_structures = 5,
220246
stoichiometry = { 'Al': num_atoms },
221-
seed = seed*1000+iter,
222-
method_ratio = {"void": method_val[0], "rand": method_val[1], "walk": method_val[2], "grow": method_val[3], "min": method_val[4]},
247+
method_ratio = methods,
223248
verbose = 0,
249+
calc = calc,
224250
)
225251

226252
# print the number of structures generated
227253
print("Total number of structures generated: ", generator.num_structures)
228-
generated_structures = generator.get_structures(calc)
229254
num_structures_new = len(generated_structures)
230255

231256
# check if directory iteration[iter] exists, if not create it
@@ -235,51 +260,63 @@ def process_structure(i, atoms, num_structures_old, calc_params, optimise_struct
235260
generator.print_settings(iterdir+"generator_settings.txt")
236261

237262
# set up list of energies
238-
energy_unrlxd = np.zeros(num_structures_new - num_structures_old)
239-
energy_rlxd = np.zeros(num_structures_new - num_structures_old)
240-
for i in range(num_structures_new - num_structures_old):
241-
write(iterdir+f"POSCAR_unrlxd_{i}", generated_structures[num_structures_old + i])
242-
print(f"Structure {i} energy per atom: {generated_structures[num_structures_old + i].get_potential_energy() / len(generated_structures[num_structures_old + i])}")
243-
unrlxd_structures.append(deepcopy(generated_structures[num_structures_old + i]))
244-
263+
for i in reversed(range(len(generated_structures))):
264+
if generated_structures[i] is None:
265+
print(f"Structure {i} is None, skipping")
266+
del generated_structures[i]
267+
continue
268+
write(iterdir+f"POSCAR_unrlxd_{i}", generated_structures[i])
269+
print(f"Structure {i} energy per atom: {generated_structures[i].get_potential_energy() / len(generated_structures[i])}")
270+
271+
245272
# Start parallel execution
246273
print("Starting parallel execution")
247274
results = Parallel(n_jobs=5)(
248-
delayed(process_structure)(i, deepcopy(generated_structures[i]), num_structures_old, calc_params, optimise_structure, iteration=seed)
249-
for i in range(num_structures_old, num_structures_new)
275+
delayed(process_structure)(i, generated_structures[i].copy(), calc_params, optimise_structure, calc=calc)
276+
for i in range(len(generated_structures))
250277
)
251278

252279
# Wait for all futures to complete
280+
energies_unrlxd = []
281+
energies_rlxd = []
253282
for j, result in enumerate(results):
254-
generated_structures[j+num_structures_old], energy_unrlxd[j], energy_rlxd[j] = result
255-
rlxd_structures.append(deepcopy(generated_structures[j+num_structures_old]))
283+
rlxd_generated_structure, energy_unrlxd, energy_rlxd = result
284+
if rlxd_generated_structure is None:
285+
print("Structure failed the checks")
286+
continue
287+
else:
288+
unrlxd_structures.append(generated_structures[j].copy())
289+
unrlxd_structures[-1].calc = SinglePointCalculator(
290+
generated_structures[j],
291+
energy=generated_structures[j].get_potential_energy(),
292+
forces=generated_structures[j].get_forces()
293+
)
294+
rlxd_structures.append(rlxd_generated_structure.copy())
295+
rlxd_structures[-1].calc = SinglePointCalculator(
296+
rlxd_generated_structure,
297+
energy=rlxd_generated_structure.get_potential_energy(),
298+
forces=rlxd_generated_structure.get_forces()
299+
)
300+
energies_unrlxd.append(energy_unrlxd)
301+
energies_rlxd.append(energy_rlxd)
256302
print("All futures completed")
303+
num_structures_new = len(energies_unrlxd)
257304

258-
# Remove structures that failed the checks
259-
for j, atoms in reversed(list(enumerate(generated_structures))):
260-
if atoms is None:
261-
energy_unrlxd = np.delete(energy_unrlxd, j-num_structures_old)
262-
energy_rlxd = np.delete(energy_rlxd, j-num_structures_old)
263-
del generated_structures[j]
264-
# del unrlxd_structures[j]
265-
del rlxd_structures[j]
266-
generator.remove_structure(j)
267-
num_structures_new = len(generated_structures)
268305

269306
# write the structures to files
270-
for i in range(num_structures_new - num_structures_old):
271-
write(iterdir+f"POSCAR_{i}", generated_structures[num_structures_old + i])
272-
print(f"Structure {i} energy per atom: {energy_rlxd[i]}")
307+
for i in range(num_structures_new):
308+
write(iterdir+f"POSCAR_{i}", rlxd_structures[num_structures_tot + i])
309+
print(f"Structure {i} energy per atom: {energies_rlxd[i]}")
273310
# append energy per atom to the 'energies_unrlxd_filename' file
274311
with open(energies_unrlxd_filename, "a") as energy_file:
275-
energy_file.write(f"{i+num_structures_old} {energy_unrlxd[i]}\n")
312+
energy_file.write(f"{i+num_structures_tot} {energies_unrlxd[i]}\n")
276313
# append energy per atom to the 'energies_rlxd_filename' file
277314
with open(energies_rlxd_filename, "a") as energy_file:
278-
energy_file.write(f"{i+num_structures_old} {energy_rlxd[i]}\n")
315+
energy_file.write(f"{i+num_structures_tot} {energies_rlxd[i]}\n")
279316

280317
# update the distribution functions
281318
print("Updating distributions")
282-
generator.distributions.update(generated_structures[num_structures_old:], from_host=False, deallocate_systems=False)
319+
generator.distributions.update(rlxd_structures[num_structures_tot:], from_host=False, deallocate_systems=False)
283320

284321
# print the new distribution functions to a file
285322
print("Printing distributions")
@@ -289,8 +326,12 @@ def process_structure(i, atoms, num_structures_old, calc_params, optimise_struct
289326
generator.distributions.write_4body(iterdir+"df4.txt")
290327
generator.distributions.deallocate_systems()
291328

329+
write(f"unrlxd_structures_seed{seed}.xyz", unrlxd_structures[num_structures_tot:], append=True)
330+
write(f"rlxd_structures_seed{seed}.xyz", rlxd_structures[num_structures_tot:], append=True)
331+
292332
# update the number of structures generated
293-
num_structures_old = num_structures_new
333+
num_structures_tot += num_structures_new
334+
294335

295336
generator.distributions.write_gdfs(f"gdfs_seed{seed}.txt")
296337

0 commit comments

Comments
 (0)