We’re going to start simple here - let’s run a local relaxation (optimize the unit cell and positions) using a pre-trained UMA model to compute formation energies for inorganic materials.
Note predicting formation energy using models that models trained solely on OMat24 must use OMat24 compatible references and corrections for mixing PBE and PBE+U calculations. We use MP2020-style corrections fitted to OMat24 DFT calculations. For more information see the documentation at the Materials Project. The necessary references can be found using the fairchem.data.omat package!
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-omatGet 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'from __future__ import annotations
import pprint
from ase.build import bulk
from ase.optimize import FIRE
from quacc.recipes.mlp.core import relax_job
from quacc import flow
from fairchem.core.calculate import FAIRChemCalculator, FormationEnergyCalculator
# Make an Atoms object of a bulk Cu structure
atoms = bulk("Cu")
# Run a structure relaxation
@flow
def relax_flow(*args, **kwargs):
return relax_job(*args, **kwargs)
result = relax_flow(
atoms,
method="fairchem",
name_or_path="uma-s-1p2",
task_name="omat",
relax_cell=True,
opt_params={"fmax": 1e-3, "optimizer": FIRE},
)
# Get the realxed atoms!
atoms = result["atoms"]
# Create an calculator using uma-s-1p2
calculator = FAIRChemCalculator.from_model_checkpoint("uma-s-1p2", task_name="omat")
# Now use the FormationEnergyCalculator to calculate the formation energy
# This will now return MP-style corrected formation energies
# For the omat task, this defaults to apply MP2020 style corrections with OMat24 compatibility
form_e_calc = FormationEnergyCalculator(calculator, apply_corrections=True)
atoms.calc = form_e_calc
form_energy = atoms.get_potential_energy()/tmp/ipykernel_9637/3292623750.py:7: DeprecationWarning: quacc.recipes.mlp is deprecated. Use quacc.recipes.mlip instead.
from quacc.recipes.mlp.core import relax_job
/tmp/ipykernel_9637/3292623750.py:7: DeprecationWarning: quacc.recipes.mlp.core is deprecated. Use quacc.recipes.mlip.core instead.
from quacc.recipes.mlp.core import relax_job
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[1], line 19
15 @flow
16 def relax_flow(*args, **kwargs):
17 return relax_job(*args, **kwargs)
18
---> 19 result = relax_flow(
20 atoms,
21 method="fairchem",
22 name_or_path="uma-s-1p2",
File ~/work/_tool/Python/3.12.13/x64/lib/python3.12/site-packages/quacc/wflow_tools/context.py:148, in tracked.<locals>.decorator.<locals>.wrapper(*args, **kwargs)
146 @wraps(func)
147 def wrapper(*args, **kwargs):
--> 148 return _tracked_call(func, node_type, args, kwargs)
File ~/work/_tool/Python/3.12.13/x64/lib/python3.12/site-packages/quacc/wflow_tools/context.py:169, in _tracked_call(func, node_type, args, kwargs)
166 # When NESTED_RESULTS is off, skip all context tracking and just
167 # delegate to the original function directly.
168 if not settings.NESTED_RESULTS:
--> 169 return func(*args, **kwargs)
171 # Create a unique name we can use at this level.
172 name = make_unique_name(prefix=f"{func.__name__}-")
Cell In[1], line 17, in relax_flow(*args, **kwargs)
15 @flow
16 def relax_flow(*args, **kwargs):
---> 17 return relax_job(*args, **kwargs)
File ~/work/_tool/Python/3.12.13/x64/lib/python3.12/site-packages/quacc/wflow_tools/context.py:148, in tracked.<locals>.decorator.<locals>.wrapper(*args, **kwargs)
146 @wraps(func)
147 def wrapper(*args, **kwargs):
--> 148 return _tracked_call(func, node_type, args, kwargs)
File ~/work/_tool/Python/3.12.13/x64/lib/python3.12/site-packages/quacc/wflow_tools/context.py:169, in _tracked_call(func, node_type, args, kwargs)
166 # When NESTED_RESULTS is off, skip all context tracking and just
167 # delegate to the original function directly.
168 if not settings.NESTED_RESULTS:
--> 169 return func(*args, **kwargs)
171 # Create a unique name we can use at this level.
172 name = make_unique_name(prefix=f"{func.__name__}-")
TypeError: relax_job() missing 1 required positional argument: 'library'pprint.pprint(f"Total energy: {result['results']['energy']} eV \n Formation energy {form_energy} eV")Compare the results to the value of -3.038 eV/atom reported in the Materials Project! Note that we expect differences due to the different DFT settings used to calculate the OMat24 training data.
Congratulations; you ran your first relaxation and predicted the formation energy of MgO using UMA and quacc!