Skip to content

Add Adsorbml recipe for MLPs #2732

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 22 commits into
base: main
Choose a base branch
from

Conversation

zulissimeta
Copy link
Contributor

@zulissimeta zulissimeta commented Mar 26, 2025

Summary of Changes

This PR adds an AdsorbML-type recipe to predict adsorption energies using a MLP.

Given a slab:

  1. Relax the slab
  2. Generate adsorbate configurations
  3. Relax each adsorbate configuration
  4. Optionally, reference the energies to the bare slab and gas phase energies (eg CO(g), H2O(g), etc)
  5. Optionally, validate the best few configurations with DFT single-points

Also, a second flow to

  1. Relax a bulk
  2. Generate slabs
  3. Run the above workflow

The total energy MLPs in the current tests are trained on PBE data, so the adsorption energies should also be PBE-level predictions (i.e. not great for small molecule adsorption energies). Using a MLP trained on RPBE data should generate results much closer to experimental adsorption energies. This is tested for OCP referenced adsorption energy predictions.

The full AdsorbML pipeline (consistent with the paper above) would be:

  1. Relax a bulk with VASP (RPBE)
  2. Generate slabs
  3. Place adsorbates
  4. Relax slabs and adsorbates, and find the top-k configurations
  5. Run a DFT single point with the same RPBE settings, and reference them correctly

Example to calculate CO binding energies on all low Miller-index facets for Cu with ML-only relaxations

from ase.build.bulk import bulk
from quacc.recipes.mlp.core import relax_job as ml_relax_job

bulk_atoms = bulk("Cu")

outputs = bulk_to_surfaces_to_adsorbml(
    bulk_atoms,
    adsorbates_kwargs=[{"adsorbate_smiles_from_db": "*CO"}],
    multiple_adsorbate_slab_config_kwargs={"num_configurations": 10},
    ml_relax_job=ml_relax_job,
    slab_validate_job=ml_relax_job,
    adslab_validate_job=ml_relax_job,
    gas_validate_job=ml_relax_job,
    bulk_relax_job=ml_relax_job,
    job_params={"all":"model_name": "EquiformerV2-31M-S2EF-OC20-All+MD",
                                    "local_cache": "./fairchem_checkpoint_cache/",
                                     "seed": 42,},
    max_miller=1,
    num_to_validate_with_DFT=0,
    reference_ml_energies_to_gas_phase=False,
    relax_bulk=False,
)

Example to also do OC20-compatible DFT single-point validations and an RPBE-compatible bulk relaxation

from ase.build.bulk import bulk
from quacc.recipes.mlp.core import relax_job as ml_relax_job
from quacc.recipes.vasp.core import relax_job as vasp_relax_job
from quacc.recipes.vasp.core import static_job as vasp_static_job
import fairchem.data.oc.utils.vasp_flags

bulk_atoms = bulk("Cu")

outputs = bulk_to_surfaces_to_adsorbml(
    bulk_atoms,
    adsorbates_kwargs=[{"adsorbate_smiles_from_db": "*CO"}],
    multiple_adsorbate_slab_config_kwargs={"num_configurations": 10},
    ml_relax_job=ml_relax_job,
    slab_validate_job=ml_relax_job,
    adslab_validate_job=vasp_static_job,
    gas_validate_job=vasp_relax_job,
    bulk_relax_job=vasp_relax_job,
    job_params={"ml_relax_job": dict(
            method="fairchem",
            model_name="EquiformerV2-153M-S2EF-OC20-All+MD",
            local_cache="./fairchem_checkpoint_cache/",
            cpu=False,
            seed=42,
        ),
        "adslab_validate_job": vasp_flags,
        "slab_validate_job": vasp_flags,
        "gas_validate_job": vasp_flags,},
    max_miller=1,
    num_to_validate_with_DFT=1,
    reference_ml_energies_to_gas_phase=False,
    relax_bulk=True,
)

Failing tests can be addressed with

  • Untangling the fairchem-core and fairchem-data-oc dependence, to allow MLP tests for adsorbml even when they can't be installed alongside fairchem-core (eg mlp2)
  • Solving what may be an unrelated error with the CHGnet static_job tests (perhaps some unpinned dependency?)

Requirements

Note: If you are an external contributor, you will see a comment from @buildbot-princeton. This is solely for the maintainers.

@buildbot-princeton
Copy link
Collaborator

Can one of the admins verify this patch?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants