Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

AdsorbML Tutorial

Tutorial Overview
PropertyValue
DifficultyIntermediate
Time20-30 minutes
PrerequisitesBasic Python, ASE
GoalFind 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.

Define desired adsorbate+slab system

from __future__ import annotations

import pandas as pd
from fairchem.data.oc.core import Bulk, Slab, Adsorbate
from ase.build import molecule

co_molecule = molecule("CO")
adsorbate = Adsorbate(adsorbate_atoms=co_molecule, adsorbate_binding_indices=[1]) # 1 corresponds to the carbon atom
# adsorbate = [Adsorbate(adsorbate_atoms=co_molecule, adsorbate_binding_indices=[1]) for _ in range(2)] # 2 COs

bulk_src_id = "mp-30"
bulk = Bulk(bulk_src_id_from_db=bulk_src_id)
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.13/x64/lib/python3.12/site-packages/fairchem/data/oc/databases/pkls/bulks.pkl...
/home/runner/work/_tool/Python/3.12.13/x64/lib/python3.12/site-packages/fairchem/data/oc/core/bulk.py:66: UserWarning: Loading data from a pickle file. Pickle files can execute arbitrary code and should only be loaded from trusted sources. Consider migrating to a safer format such as Parquet, CSV, or JSON.
  bulk_db = safe_pickle_load(fp)

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/fairchem/core/components/calculate/recipes/adsorbml.py.

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-1p2")
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'.
WARNING:root:Model is being compiled this might take a while for the first time
W0807 05:58:42.406000 10079 site-packages/torch/_logging/_internal.py:1345] [0/0] Profiler record function <class 'torch.autograd.profiler.record_function'> will be ignored
       Step     Time          Energy          fmax
LBFGS:    0 05:59:23     -300.206730        0.046073
LBFGS:    1 05:59:24     -300.207208        0.044109
LBFGS:    2 05:59:24     -300.212884        0.005262
WARNING:root:The UMA fast path (merge_mole + compile) is only available for fixed composition, task, charge, and spin. This is optimized for MD applications. Falling back to a less optimized version for subsequent evaluations. Reason: 'Compositions differ from merged model'.
Use inference_settings='batch' for heterogeneous batched evaluations.
       Step     Time          Energy          fmax
LBFGS:    0 05:59:29     -314.795148        2.141435
LBFGS:    1 05:59:29     -314.788144        2.881826
LBFGS:    2 05:59:29     -314.839770        0.952721
LBFGS:    3 05:59:30     -314.877308        1.181137
LBFGS:    4 05:59:30     -314.989679        2.018462
LBFGS:    5 05:59:30     -314.885772        3.110007
LBFGS:    6 05:59:31     -315.028830        0.882998
LBFGS:    7 05:59:31     -315.041564        0.427449
LBFGS:    8 05:59:31     -315.054959        1.149854
LBFGS:    9 05:59:32     -315.062124        0.903999
LBFGS:   10 05:59:32     -315.088886        0.610928
LBFGS:   11 05:59:33     -315.094906        0.503869
LBFGS:   12 05:59:33     -315.100559        0.184100
LBFGS:   13 05:59:33     -315.103675        0.119296
LBFGS:   14 05:59:34     -315.104936        0.194721
LBFGS:   15 05:59:34     -315.105853        0.107855
LBFGS:   16 05:59:34     -315.107375        0.180630
LBFGS:   17 05:59:35     -315.108866        0.094273
LBFGS:   18 05:59:35     -315.109317        0.046444
LBFGS:   19 05:59:35     -315.109511        0.046720
LBFGS:   20 05:59:36     -315.109873        0.074435
       Step     Time          Energy          fmax
LBFGS:    0 05:59:36     -314.839565        1.806109
LBFGS:    1 05:59:37     -314.847730        2.495788
LBFGS:    2 05:59:37     -314.896391        1.204814
LBFGS:    3 05:59:37     -315.009752        1.994792
LBFGS:    4 05:59:38     -315.066343        1.378396
LBFGS:    5 05:59:38     -315.088558        0.734318
LBFGS:    6 05:59:38     -315.095477        0.321335
LBFGS:    7 05:59:39     -315.101789        0.616317
LBFGS:    8 05:59:39     -315.107860        0.858069
LBFGS:    9 05:59:40     -315.118674        0.959352
LBFGS:   10 05:59:40     -315.126011        0.559488
LBFGS:   11 05:59:40     -315.128583        0.082887
LBFGS:   12 05:59:41     -315.128990        0.113968
LBFGS:   13 05:59:41     -315.129661        0.145818
LBFGS:   14 05:59:41     -315.130552        0.164576
LBFGS:   15 05:59:42     -315.131615        0.152383
LBFGS:   16 05:59:42     -315.132402        0.093627
LBFGS:   17 05:59:43     -315.132869        0.062064
LBFGS:   18 05:59:43     -315.133298        0.088345
LBFGS:   19 05:59:43     -315.134142        0.131693
LBFGS:   20 05:59:43     -315.135290        0.127371
       Step     Time          Energy          fmax
LBFGS:    0 05:59:44     -314.833529        1.828196
LBFGS:    1 05:59:44     -314.840662        2.517151
LBFGS:    2 05:59:44     -314.888976        1.177600
LBFGS:    3 05:59:45     -314.993000        1.923849
LBFGS:    4 05:59:45     -315.061736        1.473236
LBFGS:    5 05:59:45     -315.083261        0.780755
LBFGS:    6 05:59:46     -315.091334        0.334419
LBFGS:    7 05:59:46     -315.098084        0.679773
LBFGS:    8 05:59:47     -315.104907        0.941587
LBFGS:    9 05:59:47     -315.116419        1.018085
LBFGS:   10 05:59:47     -315.124689        0.574858
LBFGS:   11 05:59:48     -315.127464        0.078395
LBFGS:   12 05:59:48     -315.127918        0.105338
LBFGS:   13 05:59:49     -315.128520        0.134114
LBFGS:   14 05:59:49     -315.129373        0.152843
LBFGS:   15 05:59:49     -315.130356        0.143726
LBFGS:   16 05:59:50     -315.131072        0.091152
LBFGS:   17 05:59:50     -315.131485        0.061117
LBFGS:   18 05:59:50     -315.131871        0.084254
LBFGS:   19 05:59:51     -315.132628        0.127035
LBFGS:   20 05:59:51     -315.133726        0.132868
       Step     Time          Energy          fmax
LBFGS:    0 05:59:52     -314.881039        2.459260
LBFGS:    1 05:59:52     -314.869440        3.261945
LBFGS:    2 05:59:52     -314.932480        1.059515
LBFGS:    3 05:59:53     -314.966088        1.061219
LBFGS:    4 05:59:53     -315.038197        2.115876
LBFGS:    5 05:59:53     -315.070928        1.057570
LBFGS:    6 05:59:54     -315.083712        0.541704
LBFGS:    7 05:59:54     -315.087503        0.229818
LBFGS:    8 05:59:54     -315.091314        0.528073
LBFGS:    9 05:59:55     -315.097287        0.814149
LBFGS:   10 05:59:55     -315.103803        0.809158
LBFGS:   11 05:59:56     -315.109221        0.442867
LBFGS:   12 05:59:56     -315.112200        0.205370
LBFGS:   13 05:59:56     -315.114684        0.433640
LBFGS:   14 05:59:57     -315.120579        0.702702
LBFGS:   15 05:59:57     -315.127074        0.585640
LBFGS:   16 05:59:57     -315.130526        0.318653
LBFGS:   17 05:59:58     -315.132830        0.121345
LBFGS:   18 05:59:58     -315.133997        0.243018
LBFGS:   19 05:59:58     -315.136240        0.431900
LBFGS:   20 05:59:58     -315.138227        0.435469
       Step     Time          Energy          fmax
LBFGS:    0 05:59:59     -314.867245        2.197946
LBFGS:    1 05:59:59     -314.863474        3.012732
LBFGS:    2 05:59:59     -314.917633        1.110595
LBFGS:    3 06:00:00     -314.962829        1.280575
LBFGS:    4 06:00:00     -315.040138        2.305654
LBFGS:    5 06:00:00     -315.064715        0.967377
LBFGS:    6 06:00:01     -315.074418        0.262405
LBFGS:    7 06:00:01     -315.076381        0.238677
LBFGS:    8 06:00:01     -315.081069        0.602179
LBFGS:    9 06:00:01     -315.086559        0.760757
LBFGS:   10 06:00:02     -315.091339        0.569854
LBFGS:   11 06:00:02     -315.093953        0.166793
LBFGS:   12 06:00:03     -315.095036        0.170110
LBFGS:   13 06:00:03     -315.096558        0.352899
LBFGS:   14 06:00:03     -315.098835        0.429403
LBFGS:   15 06:00:04     -315.100411        0.273748
LBFGS:   16 06:00:04     -315.101007        0.086157
LBFGS:   17 06:00:04     -315.101326        0.095146
LBFGS:   18 06:00:05     -315.101720        0.182473
LBFGS:   19 06:00:05     -315.102369        0.248946
LBFGS:   20 06:00:06     -315.103030        0.206799
       Step     Time          Energy          fmax
LBFGS:    0 06:00:06     -314.794140        1.701399
LBFGS:    1 06:00:06     -314.801738        2.310897
LBFGS:    2 06:00:07     -314.847431        1.088776
LBFGS:    3 06:00:07     -314.969066        1.861005
LBFGS:    4 06:00:07     -314.985934        2.016199
LBFGS:    5 06:00:08     -315.054491        1.078070
LBFGS:    6 06:00:08     -315.075142        0.527856
LBFGS:    7 06:00:08     -315.087691        0.946278
LBFGS:    8 06:00:09     -315.095304        0.845737
LBFGS:    9 06:00:09     -315.123882        1.060214
LBFGS:   10 06:00:09     -315.129301        0.315240
LBFGS:   11 06:00:09     -315.132643        0.161050
LBFGS:   12 06:00:10     -315.134733        0.062837
LBFGS:   13 06:00:10     -315.135127        0.109286
LBFGS:   14 06:00:10     -315.135699        0.121486
LBFGS:   15 06:00:11     -315.136708        0.142399
LBFGS:   16 06:00:11     -315.137602        0.112682
LBFGS:   17 06:00:11     -315.138084        0.059147
LBFGS:   18 06:00:12     -315.138314        0.052724
LBFGS:   19 06:00:12     -315.138592        0.088448
LBFGS:   20 06:00:12     -315.139082        0.129138
       Step     Time          Energy          fmax
LBFGS:    0 06:00:13     -314.847798        1.832425
LBFGS:    1 06:00:13     -314.855084        2.552221
LBFGS:    2 06:00:13     -314.904023        1.197462
LBFGS:    3 06:00:14     -315.004787        1.933244
LBFGS:    4 06:00:14     -315.070809        1.598944
LBFGS:    5 06:00:15     -315.088251        0.687506
LBFGS:    6 06:00:15     -315.093830        0.291507
LBFGS:    7 06:00:15     -315.097343        0.483574
LBFGS:    8 06:00:16     -315.106468        0.922780
LBFGS:    9 06:00:16     -315.112912        0.840560
LBFGS:   10 06:00:16     -315.119330        0.249389
LBFGS:   11 06:00:17     -315.120239        0.102303
LBFGS:   12 06:00:17     -315.120847        0.179570
LBFGS:   13 06:00:17     -315.122037        0.258515
LBFGS:   14 06:00:18     -315.123391        0.267687
LBFGS:   15 06:00:18     -315.124545        0.193575
LBFGS:   16 06:00:19     -315.125259        0.074801
LBFGS:   17 06:00:19     -315.125750        0.106771
LBFGS:   18 06:00:19     -315.126532        0.193115
LBFGS:   19 06:00:20     -315.127900        0.265747
LBFGS:   20 06:00:20     -315.129381        0.206961
       Step     Time          Energy          fmax
LBFGS:    0 06:00:20     -314.858574        1.744812
LBFGS:    1 06:00:21     -314.868657        2.450327
LBFGS:    2 06:00:21     -314.917937        1.256103
LBFGS:    3 06:00:21     -315.046624        2.118490
LBFGS:    4 06:00:22     -315.085065        1.179874
LBFGS:    5 06:00:22     -315.100787        0.498896
LBFGS:    6 06:00:23     -315.104132        0.229950
LBFGS:    7 06:00:23     -315.108123        0.482388
LBFGS:    8 06:00:23     -315.113481        0.740029
LBFGS:    9 06:00:24     -315.119849        0.760849
LBFGS:   10 06:00:24     -315.124796        0.382979
LBFGS:   11 06:00:24     -315.126089        0.100395
LBFGS:   12 06:00:25     -315.126521        0.178094
LBFGS:   13 06:00:25     -315.128077        0.328841
LBFGS:   14 06:00:26     -315.129582        0.345138
LBFGS:   15 06:00:26     -315.130945        0.230687
LBFGS:   16 06:00:26     -315.131722        0.075233
LBFGS:   17 06:00:27     -315.132279        0.116949
LBFGS:   18 06:00:27     -315.133168        0.221920
LBFGS:   19 06:00:27     -315.134528        0.283326
LBFGS:   20 06:00:28     -315.135704        0.196118
       Step     Time          Energy          fmax
LBFGS:    0 06:00:28     -314.866755        2.417548
LBFGS:    1 06:00:28     -314.855052        3.216167
LBFGS:    2 06:00:29     -314.914733        1.042272
LBFGS:    3 06:00:29     -314.946065        1.058497
LBFGS:    4 06:00:30     -315.019230        2.146320
LBFGS:    5 06:00:30     -315.046663        1.076512
LBFGS:    6 06:00:30     -315.063891        0.617084
LBFGS:    7 06:00:31     -315.068478        0.244851
LBFGS:    8 06:00:31     -315.073796        0.596269
LBFGS:    9 06:00:31     -315.079004        0.825980
LBFGS:   10 06:00:32     -315.086693        0.848019
LBFGS:   11 06:00:32     -315.092216        0.468034
LBFGS:   12 06:00:32     -315.094491        0.114354
LBFGS:   13 06:00:33     -315.095487        0.231579
LBFGS:   14 06:00:33     -315.098065        0.382456
LBFGS:   15 06:00:34     -315.100004        0.321272
LBFGS:   16 06:00:34     -315.101024        0.174302
LBFGS:   17 06:00:34     -315.101489        0.074443
LBFGS:   18 06:00:35     -315.101848        0.109577
LBFGS:   19 06:00:35     -315.102458        0.198138
LBFGS:   20 06:00:36     -315.103302        0.223492
       Step     Time          Energy          fmax
LBFGS:    0 06:00:36     -314.993125        3.211946
LBFGS:    1 06:00:36     -314.958910        3.870611
LBFGS:    2 06:00:37     -315.053430        1.067797
LBFGS:    3 06:00:37     -315.071750        0.762624
LBFGS:    4 06:00:37     -315.104610        1.423781
LBFGS:    5 06:00:38     -315.155718        1.238123
LBFGS:    6 06:00:38     -315.164692        0.477640
LBFGS:    7 06:00:38     -315.168851        0.215179
LBFGS:    8 06:00:39     -315.171136        0.387313
LBFGS:    9 06:00:39     -315.175421        0.539187
LBFGS:   10 06:00:39     -315.178452        0.409506
LBFGS:   11 06:00:40     -315.180241        0.135608
LBFGS:   12 06:00:40     -315.181305        0.178542
LBFGS:   13 06:00:40     -315.183032        0.356822
LBFGS:   14 06:00:41     -315.185653        0.454180
LBFGS:   15 06:00:41     -315.188188        0.368469
LBFGS:   16 06:00:42     -315.189371        0.139945
LBFGS:   17 06:00:42     -315.189841        0.057226
LBFGS:   18 06:00:42     -315.190239        0.137565
LBFGS:   19 06:00:43     -315.190932        0.228825
LBFGS:   20 06:00:43     -315.191772        0.228968
top_candidates = outputs["adslabs"]
global_min_candidate = top_candidates[0]
top_candidates = outputs["adslabs"]
pd.DataFrame(top_candidates)
Loading...

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}/")