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.14/x64/lib/python3.12/site-packages/fairchem/data/oc/databases/pkls/bulks.pkl...
/home/runner/work/_tool/Python/3.12.14/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
W0916 12:36:05.968000 9764 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 12:36:45     -300.206729        0.046073
LBFGS:    1 12:36:46     -300.207206        0.044109
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.
LBFGS:    2 12:36:46     -300.212884        0.005257
       Step     Time          Energy          fmax
LBFGS:    0 12:36:53     -314.795149        2.141433
LBFGS:    1 12:36:53     -314.788145        2.881826
LBFGS:    2 12:36:54     -314.839767        0.952721
LBFGS:    3 12:36:54     -314.877307        1.181136
LBFGS:    4 12:36:54     -314.989677        2.018460
LBFGS:    5 12:36:55     -314.885770        3.109853
LBFGS:    6 12:36:55     -315.028831        0.883006
LBFGS:    7 12:36:56     -315.041564        0.427448
LBFGS:    8 12:36:56     -315.054962        1.149871
LBFGS:    9 12:36:56     -315.062122        0.904128
LBFGS:   10 12:36:57     -315.088882        0.610410
LBFGS:   11 12:36:57     -315.094909        0.504050
LBFGS:   12 12:36:58     -315.100557        0.184221
LBFGS:   13 12:36:58     -315.103668        0.119296
LBFGS:   14 12:36:58     -315.104935        0.195557
LBFGS:   15 12:36:59     -315.105849        0.107387
LBFGS:   16 12:36:59     -315.107370        0.179086
LBFGS:   17 12:37:00     -315.108864        0.094325
LBFGS:   18 12:37:00     -315.109322        0.046206
LBFGS:   19 12:37:00     -315.109509        0.046740
LBFGS:   20 12:37:01     -315.109873        0.073995
       Step     Time          Energy          fmax
LBFGS:    0 12:37:01     -314.839568        1.806109
LBFGS:    1 12:37:02     -314.847729        2.495789
LBFGS:    2 12:37:02     -314.896393        1.204814
LBFGS:    3 12:37:02     -315.009751        1.994791
LBFGS:    4 12:37:03     -315.066342        1.378423
LBFGS:    5 12:37:03     -315.088558        0.734317
LBFGS:    6 12:37:03     -315.095479        0.321336
LBFGS:    7 12:37:04     -315.101788        0.616317
LBFGS:    8 12:37:04     -315.107855        0.858069
LBFGS:    9 12:37:05     -315.118675        0.959356
LBFGS:   10 12:37:05     -315.126010        0.559489
LBFGS:   11 12:37:06     -315.128586        0.082694
LBFGS:   12 12:37:06     -315.128987        0.114203
LBFGS:   13 12:37:06     -315.129663        0.145678
LBFGS:   14 12:37:07     -315.130551        0.164772
LBFGS:   15 12:37:07     -315.131617        0.152695
LBFGS:   16 12:37:08     -315.132402        0.093733
LBFGS:   17 12:37:08     -315.132869        0.062114
LBFGS:   18 12:37:08     -315.133300        0.088311
LBFGS:   19 12:37:09     -315.134143        0.131483
LBFGS:   20 12:37:09     -315.135287        0.127987
       Step     Time          Energy          fmax
LBFGS:    0 12:37:10     -314.833526        1.828196
LBFGS:    1 12:37:10     -314.840663        2.517151
LBFGS:    2 12:37:10     -314.888977        1.177600
LBFGS:    3 12:37:11     -314.992998        1.923849
LBFGS:    4 12:37:11     -315.061733        1.473236
LBFGS:    5 12:37:11     -315.083261        0.780754
LBFGS:    6 12:37:12     -315.091335        0.334419
LBFGS:    7 12:37:12     -315.098083        0.679773
LBFGS:    8 12:37:13     -315.104906        0.941586
LBFGS:    9 12:37:13     -315.116421        1.018084
LBFGS:   10 12:37:13     -315.124689        0.574871
LBFGS:   11 12:37:14     -315.127465        0.078397
LBFGS:   12 12:37:14     -315.127918        0.105349
LBFGS:   13 12:37:14     -315.128521        0.134126
LBFGS:   14 12:37:15     -315.129374        0.152842
LBFGS:   15 12:37:15     -315.130356        0.143694
LBFGS:   16 12:37:16     -315.131073        0.090975
LBFGS:   17 12:37:16     -315.131485        0.061055
LBFGS:   18 12:37:16     -315.131868        0.084162
LBFGS:   19 12:37:17     -315.132628        0.127399
LBFGS:   20 12:37:17     -315.133726        0.132808
       Step     Time          Energy          fmax
LBFGS:    0 12:37:18     -314.881037        2.459259
LBFGS:    1 12:37:18     -314.869442        3.261945
LBFGS:    2 12:37:18     -314.932477        1.059515
LBFGS:    3 12:37:19     -314.966090        1.061219
LBFGS:    4 12:37:19     -315.038194        2.115853
LBFGS:    5 12:37:20     -315.070930        1.057595
LBFGS:    6 12:37:20     -315.083713        0.541704
LBFGS:    7 12:37:20     -315.087505        0.229829
LBFGS:    8 12:37:21     -315.091316        0.527931
LBFGS:    9 12:37:21     -315.097286        0.814268
LBFGS:   10 12:37:22     -315.103799        0.809236
LBFGS:   11 12:37:22     -315.109222        0.442678
LBFGS:   12 12:37:22     -315.112197        0.205210
LBFGS:   13 12:37:23     -315.114687        0.433726
LBFGS:   14 12:37:23     -315.120577        0.702478
LBFGS:   15 12:37:24     -315.127071        0.585907
LBFGS:   16 12:37:24     -315.130525        0.318726
LBFGS:   17 12:37:24     -315.132831        0.121361
LBFGS:   18 12:37:25     -315.133999        0.242977
LBFGS:   19 12:37:25     -315.136235        0.431755
LBFGS:   20 12:37:26     -315.138227        0.435423
       Step     Time          Energy          fmax
LBFGS:    0 12:37:26     -314.867244        2.197946
LBFGS:    1 12:37:26     -314.863475        3.012733
LBFGS:    2 12:37:27     -314.917634        1.110596
LBFGS:    3 12:37:27     -314.962830        1.280575
LBFGS:    4 12:37:27     -315.040137        2.305654
LBFGS:    5 12:37:28     -315.064716        0.967378
LBFGS:    6 12:37:28     -315.074422        0.262405
LBFGS:    7 12:37:29     -315.076378        0.238677
LBFGS:    8 12:37:29     -315.081073        0.602179
LBFGS:    9 12:37:29     -315.086561        0.760757
LBFGS:   10 12:37:30     -315.091338        0.569855
LBFGS:   11 12:37:30     -315.093950        0.166773
LBFGS:   12 12:37:30     -315.095036        0.170111
LBFGS:   13 12:37:31     -315.096556        0.352872
LBFGS:   14 12:37:31     -315.098836        0.429550
LBFGS:   15 12:37:32     -315.100409        0.273663
LBFGS:   16 12:37:32     -315.101005        0.086187
LBFGS:   17 12:37:32     -315.101324        0.095240
LBFGS:   18 12:37:33     -315.101720        0.182371
LBFGS:   19 12:37:33     -315.102369        0.248912
LBFGS:   20 12:37:34     -315.103026        0.206940
       Step     Time          Energy          fmax
LBFGS:    0 12:37:34     -314.794139        1.701399
LBFGS:    1 12:37:34     -314.801735        2.310896
LBFGS:    2 12:37:35     -314.847432        1.088776
LBFGS:    3 12:37:35     -314.969065        1.861005
LBFGS:    4 12:37:36     -314.985934        2.016199
LBFGS:    5 12:37:36     -315.054490        1.078070
LBFGS:    6 12:37:36     -315.075142        0.527855
LBFGS:    7 12:37:37     -315.087692        0.946277
LBFGS:    8 12:37:37     -315.095303        0.845892
LBFGS:    9 12:37:38     -315.123891        1.058942
LBFGS:   10 12:37:38     -315.129305        0.315299
LBFGS:   11 12:37:38     -315.132643        0.161403
LBFGS:   12 12:37:39     -315.134736        0.061979
LBFGS:   13 12:37:39     -315.135125        0.109007
LBFGS:   14 12:37:40     -315.135703        0.120920
LBFGS:   15 12:37:40     -315.136710        0.141593
LBFGS:   16 12:37:40     -315.137602        0.111676
LBFGS:   17 12:37:41     -315.138084        0.059164
LBFGS:   18 12:37:41     -315.138317        0.052877
LBFGS:   19 12:37:41     -315.138589        0.087909
LBFGS:   20 12:37:42     -315.139085        0.128314
       Step     Time          Energy          fmax
LBFGS:    0 12:37:42     -314.847799        1.832425
LBFGS:    1 12:37:43     -314.855084        2.552221
LBFGS:    2 12:37:43     -314.904019        1.197462
LBFGS:    3 12:37:44     -315.004788        1.933244
LBFGS:    4 12:37:44     -315.070812        1.598957
LBFGS:    5 12:37:44     -315.088253        0.687507
LBFGS:    6 12:37:45     -315.093831        0.291513
LBFGS:    7 12:37:45     -315.097347        0.483570
LBFGS:    8 12:37:46     -315.106470        0.922653
LBFGS:    9 12:37:46     -315.112912        0.840615
LBFGS:   10 12:37:46     -315.119330        0.249201
LBFGS:   11 12:37:47     -315.120236        0.102208
LBFGS:   12 12:37:47     -315.120844        0.179697
LBFGS:   13 12:37:48     -315.122035        0.258287
LBFGS:   14 12:37:48     -315.123393        0.268285
LBFGS:   15 12:37:48     -315.124549        0.193485
LBFGS:   16 12:37:49     -315.125260        0.074754
LBFGS:   17 12:37:49     -315.125747        0.106576
LBFGS:   18 12:37:50     -315.126532        0.193366
LBFGS:   19 12:37:50     -315.127900        0.265545
LBFGS:   20 12:37:50     -315.129380        0.206838
       Step     Time          Energy          fmax
LBFGS:    0 12:37:51     -314.858577        1.744813
LBFGS:    1 12:37:51     -314.868656        2.450326
LBFGS:    2 12:37:52     -314.917940        1.256103
LBFGS:    3 12:37:52     -315.046626        2.118490
LBFGS:    4 12:37:52     -315.085064        1.179873
LBFGS:    5 12:37:53     -315.100786        0.498899
LBFGS:    6 12:37:53     -315.104130        0.229950
LBFGS:    7 12:37:53     -315.108119        0.482388
LBFGS:    8 12:37:54     -315.113483        0.740029
LBFGS:    9 12:37:54     -315.119850        0.760850
LBFGS:   10 12:37:55     -315.124795        0.382975
LBFGS:   11 12:37:55     -315.126087        0.100397
LBFGS:   12 12:37:55     -315.126520        0.178096
LBFGS:   13 12:37:56     -315.128077        0.328851
LBFGS:   14 12:37:56     -315.129583        0.345150
LBFGS:   15 12:37:57     -315.130946        0.230816
LBFGS:   16 12:37:57     -315.131726        0.075050
LBFGS:   17 12:37:57     -315.132279        0.116782
LBFGS:   18 12:37:58     -315.133167        0.222263
LBFGS:   19 12:37:58     -315.134528        0.283227
LBFGS:   20 12:37:59     -315.135706        0.195912
       Step     Time          Energy          fmax
LBFGS:    0 12:37:59     -314.866754        2.417548
LBFGS:    1 12:37:59     -314.855053        3.216167
LBFGS:    2 12:38:00     -314.914733        1.042271
LBFGS:    3 12:38:00     -314.946060        1.058496
LBFGS:    4 12:38:01     -315.019229        2.146319
LBFGS:    5 12:38:01     -315.046663        1.076485
LBFGS:    6 12:38:01     -315.063892        0.617087
LBFGS:    7 12:38:02     -315.068479        0.244851
LBFGS:    8 12:38:02     -315.073798        0.596252
LBFGS:    9 12:38:02     -315.079008        0.825980
LBFGS:   10 12:38:03     -315.086690        0.847972
LBFGS:   11 12:38:03     -315.092214        0.468033
LBFGS:   12 12:38:04     -315.094493        0.114355
LBFGS:   13 12:38:04     -315.095490        0.231722
LBFGS:   14 12:38:04     -315.098066        0.381974
LBFGS:   15 12:38:05     -315.100006        0.321596
LBFGS:   16 12:38:05     -315.101023        0.174167
LBFGS:   17 12:38:06     -315.101487        0.074597
LBFGS:   18 12:38:06     -315.101848        0.109762
LBFGS:   19 12:38:06     -315.102457        0.198190
LBFGS:   20 12:38:07     -315.103300        0.223583
       Step     Time          Energy          fmax
LBFGS:    0 12:38:07     -314.993120        3.211945
LBFGS:    1 12:38:08     -314.958909        3.870611
LBFGS:    2 12:38:08     -315.053430        1.067796
LBFGS:    3 12:38:08     -315.071751        0.762625
LBFGS:    4 12:38:09     -315.104608        1.423780
LBFGS:    5 12:38:09     -315.155714        1.238123
LBFGS:    6 12:38:10     -315.164694        0.477485
LBFGS:    7 12:38:10     -315.168853        0.215178
LBFGS:    8 12:38:10     -315.171137        0.387432
LBFGS:    9 12:38:11     -315.175414        0.539389
LBFGS:   10 12:38:11     -315.178451        0.409807
LBFGS:   11 12:38:12     -315.180236        0.135780
LBFGS:   12 12:38:12     -315.181306        0.178262
LBFGS:   13 12:38:12     -315.183033        0.356964
LBFGS:   14 12:38:13     -315.185648        0.454328
LBFGS:   15 12:38:13     -315.188188        0.368622
LBFGS:   16 12:38:14     -315.189371        0.140116
LBFGS:   17 12:38:14     -315.189841        0.057126
LBFGS:   18 12:38:14     -315.190238        0.137571
LBFGS:   19 12:38:15     -315.190932        0.228825
LBFGS:   20 12:38:15     -315.191769        0.228966
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}/")