Skip to content

Commit da08b4a

Browse files
committed
r1 cation effects
1 parent 2cebfa4 commit da08b4a

2 files changed

Lines changed: 145 additions & 0 deletions

File tree

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
from ase.build import fcc111
2+
from autoadsorbate import Fragment, Surface
3+
from ase.io import write
4+
import uuid
5+
import base64
6+
7+
def generate_uid(length=5):
8+
"""Generate a short UID from UUID4 using base64 encoding."""
9+
uid = str(uuid.uuid4())
10+
# Convert to base64 and take first N characters
11+
encoded = base64.urlsafe_b64encode(uid.encode()).decode()
12+
return encoded[:length]
13+
14+
def make_smiles_plus(surface, smiles_plus):
15+
16+
traj = []
17+
for smile in smiles_plus:
18+
19+
fragment = Fragment(smile, to_initialize=fragment_conformers)
20+
21+
traj += surface.get_populated_sites(
22+
fragment,
23+
site_index='all',
24+
sample_rotation=True, mode='heuristic',
25+
conformers_per_site_cap=5, overlap_thr=1.5, verbose=False
26+
)
27+
28+
out_traj = []
29+
for cation in cations:
30+
for atoms in traj:
31+
a = atoms.copy()
32+
cf = fragment.get_conformer(0)
33+
adsorbate_formula = cf[
34+
[atom.index for atom in cf if atom.symbol in ['C', 'H', 'O']]
35+
].get_chemical_formula(empirical=True)
36+
a.info['adsorbate_info']['adsorbate_formula'] = adsorbate_formula
37+
a.info['adsorbate_info']['cation'] = cation
38+
a[-1].symbol = cation
39+
out_traj+=[a]
40+
return out_traj
41+
42+
43+
def make_smiles(surface, smiles):
44+
45+
traj = []
46+
for smile in smiles:
47+
48+
fragment = Fragment(smile, to_initialize=fragment_conformers)
49+
50+
traj += surface.get_populated_sites(
51+
fragment,
52+
site_index='all',
53+
sample_rotation=True, mode='heuristic',
54+
conformers_per_site_cap=5, overlap_thr=1.5, verbose=False
55+
)
56+
57+
for atoms in traj:
58+
atoms.info['adsorbate_info']['cation'] = 'None'
59+
60+
return traj
61+
62+
63+
def main():
64+
slab = fcc111(slab_metal, size=slab_size, vacuum=10)
65+
surface = Surface(slab)
66+
surface.sym_reduce()
67+
68+
out_traj = []
69+
out_traj += make_smiles(surface, smiles)
70+
out_traj += make_smiles_plus(surface, smiles_plus)
71+
72+
for a in out_traj:
73+
a.info['uid'] = generate_uid()
74+
75+
print(f'Writing. . . {len(out_traj) = }, {out_filename = }')
76+
write(out_filename, out_traj)
77+
78+
79+
###################### user input
80+
81+
slab_metal = 'Cu'
82+
slab_size = [4,4,4]
83+
fragment_conformers = 10
84+
cations = ['Na','K','Li','Cs']
85+
out_filename = 'generated_traj.xyz'
86+
87+
smiles = [
88+
'ClC(=O)[O-]',
89+
'Cl[O+]=C([O-])[O-]',
90+
'ClC(=C=O)[O-]',
91+
'S1SOC([O-])=C1[O-]',
92+
]
93+
94+
smiles_plus = [ #using a similar hack as for the surrogate atom.
95+
'ClC(=O)OCl',
96+
'Cl[O+]=C(O2)OS2',
97+
'ClC(=C=O)OCl',
98+
'S1SOC(O2)=C1OS2',
99+
]
100+
101+
if __name__ == '__main__':
102+
main()

scripts/cation_fragments/relax.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import time
2+
import os
3+
from glob import glob
4+
from joblib import Parallel, delayed
5+
6+
import pandas as pd
7+
import numpy as np
8+
9+
import ase
10+
from ase.optimize import BFGS
11+
from ase import units
12+
from ase.constraints import FixAtoms
13+
14+
from mace.calculators import mace_mp
15+
from pathlib import Path
16+
17+
import sys
18+
from autoadsorbate.utils import freeze_atoms, save_relax_config, relaxatoms
19+
20+
rcut=40
21+
steps = 500
22+
fmax = 0.05
23+
disp=True
24+
prefix = 'MACE_prerelax'
25+
freeze_bottom=False
26+
traj = ase.io.read('./generated_traj.xyz', index = ':')
27+
28+
29+
def main():
30+
31+
macemp = mace_mp(model='medium',dispersion=disp,device="cpu",dispersion_cutoff=rcut* units.Bohr, default_dtype="float64")
32+
33+
for atoms in traj:
34+
c = FixAtoms(mask=[atoms.arrays['fragments'][atom.index] == 0 for atom in atoms])
35+
atoms.set_constraint(c)
36+
37+
38+
for atoms in traj:
39+
relaxatoms(atoms, macemp, prefix, steps=steps, freeze_bottom=freeze_bottom, fmax=fmax)
40+
41+
42+
if __name__ == '__main__':
43+
main()

0 commit comments

Comments
 (0)