| Property | Value |
|---|---|
| Difficulty | Intermediate |
| Time | 20-30 minutes |
| Prerequisites | Basic Python, ASE |
| Goal | Find optimal adsorption sites using ML-accelerated relaxations |
The AdsorbML paper showed that pre-trained machine learning potentials were now viable to find and prioritize the best adsorption sites for a given surface. The results were quite impressive, especially if you were willing to do a DFT single-point calculation on the best calculations.
The latest UMA models are now total-energy models, and the results for the adsorption energy are even more impressive (see the paper for details and benchmarks). The AdsorbML package helps you with automated multi-adsorbate placement, and will automatically run calculations using the ML models to find the best sites to sample.
Need to install fairchem-core or get UMA access or getting permissions/401 errors?
Install the necessary packages using pip, uv etc
! pip install fairchem-core fairchem-data-oc fairchem-applications-cattsunamiGet access to any necessary huggingface gated models
Get and login to your Huggingface account
Request access to https://
huggingface .co /facebook /UMA Create a Huggingface token at https://
huggingface .co /settings /tokens/ with the permission “Permissions: Read access to contents of all public gated repos you can access” Add the token as an environment variable using
huggingface-cli loginor by setting the HF_TOKEN environment variable.
# Login using the huggingface-cli utility
! huggingface-cli login
# alternatively,
import os
os.environ['HF_TOKEN'] = 'MY_TOKEN'Define desired adsorbate+slab system¶
from __future__ import annotations
import pandas as pd
from fairchem.data.oc.core import Adsorbate, Bulk, Slab
bulk_src_id = "mp-30"
adsorbate_smiles = "*CO"
bulk = Bulk(bulk_src_id_from_db=bulk_src_id)
adsorbate = Adsorbate(adsorbate_smiles_from_db=adsorbate_smiles)
slabs = Slab.from_bulk_get_specific_millers(bulk=bulk, specific_millers=(1, 1, 1))
# There may be multiple slabs with this miller index.
# For demonstrative purposes we will take the first entry.
slab = slabs[0]Downloading /home/runner/work/_tool/Python/3.12.12/x64/lib/python3.12/site-packages/fairchem/data/oc/databases/pkls/bulks.pkl...
Run heuristic/random adsorbate placement and ML relaxations¶
Now that we’ve defined the bulk, slab, and adsorbates of interest, we can quickly use the pre-trained UMA model as a calculator and the helper script fairchem.core.components.calculate.recipes.adsorbml.run_adsorbml. More details on the automated pipeline can be found at src
from ase.optimize import LBFGS
from fairchem.core import FAIRChemCalculator, pretrained_mlip
from fairchem.core.components.calculate.recipes.adsorbml import run_adsorbml
predictor = pretrained_mlip.get_predict_unit("uma-s-1p1")
calc = FAIRChemCalculator(predictor, task_name="oc20")
outputs = run_adsorbml(
slab=slab,
adsorbate=adsorbate,
calculator=calc,
optimizer_cls=LBFGS,
fmax=0.02,
steps=20, # Increase to 200 for practical application, 20 is used for demonstrations
num_placements=10, # Increase to 100 for practical application, 10 is used for demonstrations
reference_ml_energies=True, # True if using a total energy model (i.e. UMA)
relaxed_slab_atoms=None,
place_on_relaxed_slab=False,
)WARNING:root:device was not explicitly set, using device='cuda'.
Step Time Energy fmax
LBFGS: 0 19:09:39 -300.219297 0.047121
LBFGS: 1 19:09:40 -300.219797 0.045099
LBFGS: 2 19:09:41 -300.225582 0.004437
/home/runner/work/_tool/Python/3.12.12/x64/lib/python3.12/site-packages/fairchem/data/oc/core/adsorbate.py:89: UserWarning: An adsorbate with that SMILES string was not found. Choosing one at random instead.
warnings.warn(
Step Time Energy fmax
LBFGS: 0 19:09:42 -329.009720 2.969513
LBFGS: 1 19:09:42 -329.262835 1.461637
LBFGS: 2 19:09:43 -329.394583 0.970980
LBFGS: 3 19:09:43 -329.437779 0.865683
LBFGS: 4 19:09:44 -329.510420 0.710856
LBFGS: 5 19:09:45 -329.535748 0.527360
LBFGS: 6 19:09:45 -329.547663 0.368447
LBFGS: 7 19:09:46 -329.559617 0.412711
LBFGS: 8 19:09:47 -329.577611 0.612602
LBFGS: 9 19:09:47 -329.603840 0.625859
LBFGS: 10 19:09:48 -329.627186 0.542650
LBFGS: 11 19:09:48 -329.650075 0.598596
LBFGS: 12 19:09:49 -329.681857 0.556511
LBFGS: 13 19:09:50 -329.724486 0.899005
LBFGS: 14 19:09:50 -329.774590 1.075232
LBFGS: 15 19:09:51 -329.824793 0.864809
LBFGS: 16 19:09:52 -329.859660 0.402836
LBFGS: 17 19:09:52 -329.880381 0.496898
LBFGS: 18 19:09:53 -329.913308 0.741621
LBFGS: 19 19:09:53 -329.952433 0.844013
LBFGS: 20 19:09:54 -329.978152 0.518027
Step Time Energy fmax
LBFGS: 0 19:09:55 -328.863087 3.004485
LBFGS: 1 19:09:55 -329.128968 1.449173
LBFGS: 2 19:09:56 -329.297528 1.136906
LBFGS: 3 19:09:56 -329.349667 1.035493
LBFGS: 4 19:09:57 -329.443007 0.754109
LBFGS: 5 19:09:58 -329.470627 0.464105
LBFGS: 6 19:09:58 -329.485615 0.474587
LBFGS: 7 19:09:59 -329.507039 0.504762
LBFGS: 8 19:10:00 -329.534361 0.710300
LBFGS: 9 19:10:00 -329.564248 0.611038
LBFGS: 10 19:10:01 -329.587147 0.594256
LBFGS: 11 19:10:01 -329.618104 0.758023
LBFGS: 12 19:10:02 -329.666066 0.844121
LBFGS: 13 19:10:02 -329.731738 0.960196
LBFGS: 14 19:10:03 -329.812537 1.099739
LBFGS: 15 19:10:03 -329.892560 0.743060
LBFGS: 16 19:10:04 -329.941866 0.452568
LBFGS: 17 19:10:04 -329.968739 0.471418
LBFGS: 18 19:10:05 -329.997143 0.400162
LBFGS: 19 19:10:06 -330.011363 0.935456
LBFGS: 20 19:10:06 -330.021752 0.585527
Step Time Energy fmax
LBFGS: 0 19:10:07 -329.256674 2.819493
LBFGS: 1 19:10:07 -329.460396 1.434213
LBFGS: 2 19:10:08 -329.577994 0.942241
LBFGS: 3 19:10:09 -329.612786 0.876027
LBFGS: 4 19:10:09 -329.669688 0.456017
LBFGS: 5 19:10:10 -329.683718 0.335064
LBFGS: 6 19:10:11 -329.692034 0.361890
LBFGS: 7 19:10:11 -329.702542 0.349887
LBFGS: 8 19:10:12 -329.719109 0.538404
LBFGS: 9 19:10:12 -329.736926 0.499436
LBFGS: 10 19:10:13 -329.751368 0.440201
LBFGS: 11 19:10:14 -329.768120 0.522411
LBFGS: 12 19:10:14 -329.793059 0.593161
LBFGS: 13 19:10:15 -329.825989 0.699339
LBFGS: 14 19:10:15 -329.863444 0.737224
LBFGS: 15 19:10:16 -329.897252 0.451706
LBFGS: 16 19:10:17 -329.919163 0.308388
LBFGS: 17 19:10:17 -329.939772 0.458414
LBFGS: 18 19:10:18 -329.970372 0.587960
LBFGS: 19 19:10:19 -329.996241 0.462124
LBFGS: 20 19:10:19 -330.011384 0.346891
Step Time Energy fmax
LBFGS: 0 19:10:20 -329.205535 2.770493
LBFGS: 1 19:10:21 -329.425767 1.349016
LBFGS: 2 19:10:21 -329.544640 0.934491
LBFGS: 3 19:10:22 -329.576279 0.841544
LBFGS: 4 19:10:22 -329.634009 0.618370
LBFGS: 5 19:10:23 -329.649130 0.403423
LBFGS: 6 19:10:24 -329.658309 0.343099
LBFGS: 7 19:10:24 -329.670218 0.412106
LBFGS: 8 19:10:25 -329.686520 0.494451
LBFGS: 9 19:10:26 -329.702441 0.360513
LBFGS: 10 19:10:26 -329.715127 0.422155
LBFGS: 11 19:10:27 -329.731505 0.524086
LBFGS: 12 19:10:28 -329.758105 0.593310
LBFGS: 13 19:10:28 -329.797152 0.846374
LBFGS: 14 19:10:29 -329.845612 0.867895
LBFGS: 15 19:10:29 -329.893467 0.532800
LBFGS: 16 19:10:30 -329.922970 0.297055
LBFGS: 17 19:10:31 -329.944394 0.413075
LBFGS: 18 19:10:31 -329.975647 0.534601
LBFGS: 19 19:10:32 -330.004639 0.488152
LBFGS: 20 19:10:33 -330.024415 0.446784
Step Time Energy fmax
LBFGS: 0 19:10:33 -329.211249 2.539020
LBFGS: 1 19:10:34 -329.424620 1.304846
LBFGS: 2 19:10:34 -329.546065 0.967964
LBFGS: 3 19:10:35 -329.582848 0.843348
LBFGS: 4 19:10:36 -329.649565 0.715533
LBFGS: 5 19:10:36 -329.668446 0.470573
LBFGS: 6 19:10:37 -329.680207 0.335346
LBFGS: 7 19:10:38 -329.694863 0.424289
LBFGS: 8 19:10:38 -329.717118 0.593557
LBFGS: 9 19:10:39 -329.741149 0.510368
LBFGS: 10 19:10:39 -329.759749 0.553036
LBFGS: 11 19:10:40 -329.783667 0.671059
LBFGS: 12 19:10:41 -329.818923 0.717816
LBFGS: 13 19:10:41 -329.866856 0.852129
LBFGS: 14 19:10:42 -329.926055 0.900631
LBFGS: 15 19:10:42 -329.983866 0.579040
LBFGS: 16 19:10:43 -330.014615 0.273318
LBFGS: 17 19:10:44 -330.030867 0.295796
LBFGS: 18 19:10:44 -330.050536 0.347294
LBFGS: 19 19:10:45 -330.073638 0.688606
LBFGS: 20 19:10:46 -330.085513 0.523955
Step Time Energy fmax
LBFGS: 0 19:10:46 -329.135085 2.582890
LBFGS: 1 19:10:47 -329.367688 1.265373
LBFGS: 2 19:10:48 -329.494570 1.086841
LBFGS: 3 19:10:48 -329.540064 0.986831
LBFGS: 4 19:10:49 -329.625926 0.962412
LBFGS: 5 19:10:50 -329.667471 0.662274
LBFGS: 6 19:10:50 -329.689782 0.509090
LBFGS: 7 19:10:51 -329.717732 0.575157
LBFGS: 8 19:10:51 -329.760651 0.709058
LBFGS: 9 19:10:52 -329.811249 0.742547
LBFGS: 10 19:10:53 -329.849524 0.627476
LBFGS: 11 19:10:53 -329.893954 0.795612
LBFGS: 12 19:10:54 -329.935397 0.857878
LBFGS: 13 19:10:54 -329.992932 0.844224
LBFGS: 14 19:10:55 -330.053818 0.867204
LBFGS: 15 19:10:56 -330.108368 0.605135
LBFGS: 16 19:10:56 -330.132178 0.436328
LBFGS: 17 19:10:57 -330.136284 0.501747
LBFGS: 18 19:10:57 -330.148593 0.282022
LBFGS: 19 19:10:58 -330.156363 0.200744
LBFGS: 20 19:10:59 -330.171837 0.240254
Step Time Energy fmax
LBFGS: 0 19:10:59 -328.733916 3.200605
LBFGS: 1 19:11:00 -328.991669 1.490291
LBFGS: 2 19:11:01 -329.154738 1.069547
LBFGS: 3 19:11:01 -329.214303 1.158683
LBFGS: 4 19:11:02 -329.306176 0.880186
LBFGS: 5 19:11:03 -329.354765 0.521455
LBFGS: 6 19:11:03 -329.373816 0.406390
LBFGS: 7 19:11:04 -329.392216 0.423459
LBFGS: 8 19:11:04 -329.424120 0.793771
LBFGS: 9 19:11:05 -329.471205 0.983876
LBFGS: 10 19:11:06 -329.517493 0.720482
LBFGS: 11 19:11:06 -329.554766 0.678926
LBFGS: 12 19:11:07 -329.605507 0.670628
LBFGS: 13 19:11:08 -329.668789 1.013306
LBFGS: 14 19:11:08 -329.743601 1.208141
LBFGS: 15 19:11:09 -329.825654 1.019960
LBFGS: 16 19:11:09 -329.894019 0.502951
LBFGS: 17 19:11:10 -329.929640 0.549676
LBFGS: 18 19:11:11 -329.969433 0.775313
LBFGS: 19 19:11:11 -330.012423 0.637122
LBFGS: 20 19:11:12 -330.041602 0.639321
Step Time Energy fmax
LBFGS: 0 19:11:12 -328.812851 3.139527
LBFGS: 1 19:11:13 -329.104134 1.659777
LBFGS: 2 19:11:14 -329.261296 1.063189
LBFGS: 3 19:11:14 -329.315392 0.941084
LBFGS: 4 19:11:15 -329.401927 0.762254
LBFGS: 5 19:11:15 -329.432644 0.585094
LBFGS: 6 19:11:16 -329.447833 0.387267
LBFGS: 7 19:11:16 -329.464148 0.482829
LBFGS: 8 19:11:17 -329.488942 0.754020
LBFGS: 9 19:11:18 -329.530213 0.830477
LBFGS: 10 19:11:18 -329.567841 0.643475
LBFGS: 11 19:11:19 -329.601157 0.690259
LBFGS: 12 19:11:20 -329.642039 0.614270
LBFGS: 13 19:11:20 -329.693690 0.974768
LBFGS: 14 19:11:21 -329.754921 1.237395
LBFGS: 15 19:11:22 -329.820443 1.103491
LBFGS: 16 19:11:22 -329.870160 0.439136
LBFGS: 17 19:11:23 -329.893593 0.480331
LBFGS: 18 19:11:23 -329.922291 0.646453
LBFGS: 19 19:11:24 -329.961438 0.807287
LBFGS: 20 19:11:25 -329.985346 0.502254
Step Time Energy fmax
LBFGS: 0 19:11:25 -329.314454 2.736768
LBFGS: 1 19:11:26 -329.518334 1.399364
LBFGS: 2 19:11:26 -329.630576 0.889363
LBFGS: 3 19:11:27 -329.660500 0.798830
LBFGS: 4 19:11:28 -329.712327 0.471946
LBFGS: 5 19:11:28 -329.722420 0.285260
LBFGS: 6 19:11:29 -329.729035 0.291240
LBFGS: 7 19:11:30 -329.737357 0.353161
LBFGS: 8 19:11:30 -329.748871 0.425706
LBFGS: 9 19:11:31 -329.759114 0.313416
LBFGS: 10 19:11:32 -329.767615 0.363693
LBFGS: 11 19:11:32 -329.779284 0.441905
LBFGS: 12 19:11:33 -329.798659 0.552678
LBFGS: 13 19:11:33 -329.826350 0.683729
LBFGS: 14 19:11:33 -329.857178 0.620631
LBFGS: 15 19:11:34 -329.881236 0.312430
LBFGS: 16 19:11:35 -329.894885 0.283809
LBFGS: 17 19:11:35 -329.911227 0.489756
LBFGS: 18 19:11:36 -329.941632 0.716169
LBFGS: 19 19:11:36 -329.974209 0.678506
LBFGS: 20 19:11:37 -329.992060 0.306098
Step Time Energy fmax
LBFGS: 0 19:11:38 -329.228392 2.918154
LBFGS: 1 19:11:38 -329.437798 1.484230
LBFGS: 2 19:11:39 -329.555560 0.932674
LBFGS: 3 19:11:39 -329.590766 0.872412
LBFGS: 4 19:11:40 -329.650162 0.486967
LBFGS: 5 19:11:41 -329.665318 0.335052
LBFGS: 6 19:11:41 -329.674771 0.327719
LBFGS: 7 19:11:42 -329.686377 0.376811
LBFGS: 8 19:11:43 -329.703900 0.557212
LBFGS: 9 19:11:43 -329.722813 0.502451
LBFGS: 10 19:11:44 -329.738276 0.468258
LBFGS: 11 19:11:45 -329.756320 0.528995
LBFGS: 12 19:11:45 -329.783688 0.643324
LBFGS: 13 19:11:46 -329.821875 0.804526
LBFGS: 14 19:11:47 -329.866316 0.804846
LBFGS: 15 19:11:47 -329.906355 0.506080
LBFGS: 16 19:11:48 -329.928635 0.355012
LBFGS: 17 19:11:48 -329.945220 0.405427
LBFGS: 18 19:11:49 -329.975024 0.566548
LBFGS: 19 19:11:50 -330.004456 0.510450
LBFGS: 20 19:11:50 -330.020985 0.304272
top_candidates = outputs["adslabs"]
global_min_candidate = top_candidates[0]top_candidates = outputs["adslabs"]
pd.DataFrame(top_candidates)Write VASP input files¶
If you want to verify the results, you should run VASP. This assumes you have access to VASP pseudopotentials. The default VASP flags (which are equivalent to those used to make OC20) are located in ocdata.utils.vasp. Alternatively, you may pass your own vasp flags to the write_vasp_input_files function as vasp_flags. Note that to run this you need access to the VASP pseudopotentials and need to have those set up in ASE.
import os
from fairchem.data.oc.utils.vasp import write_vasp_input_files
# Grab the 5 systems with the lowest energy
top_5_candidates = top_candidates[:5]
# Write the inputs
for idx, config in enumerate(top_5_candidates):
os.makedirs(f"data/{idx}", exist_ok=True)
write_vasp_input_files(config["atoms"], outdir=f"data/{idx}/")