Closed zulissi closed 6 months ago
I think it's because the pre-trained checkpoint is trained with quadruplets and we can't calculate that for H20. So this checkpoint would not work for systems with number of atoms < 4
I see a similar error with bulk systems:
from ocpmodels.common.relaxation.ase_utils import OCPCalculator
from ase import Atom, Atoms
import numpy as np
cp = "gemnet_oc_large_s2ef_all_md.pt"
calc = OCPCalculator(checkpoint=cp, trainer='energy')
# fcc
a = 3.6
atoms = Atoms([Atom('Pt', (0, 0, 0))],
cell=0.5 * a * np.array([[1.0, 1.0, 0.0],
[0.0, 1.0, 1.0],
[1.0, 0.0, 1.0]]),
pbc=True)
atoms = atoms.repeat((3, 3, 3))
atoms.calc = calc
print(atoms.get_potential_energy())
eventually errors out with RuntimeError: cannot reshape tensor of 0 elements into shape [0, -1] because the unspecified dimension size -1 can be any value and is ambiguous
that unit cell has 27 atoms in it.
Since you didn't set the tags for this system, by default it assumes it to be 0 and doesn't calculate quadruplets. If you could do something like
tags = np.ones(len(atoms))
atoms.set_tags(tags)
it should give you the required result
That the GemNet-OC pre-trained checkpoints cannot be used with gas molecules with <4 atoms, Does this mean that the adsorption energies(between bulk and gas) cannot be calculated with the OCP Calculator using the published OC22 trained models (gemnet-OC, OC20+OC22 and OC20->OC22)?
We calculate gas phase energies by using per-atomic energy contributions which we get from a linear combination of energies of N2, H2O, CO, and H2. These pre-calculated per-atomic energies can be found in the supplementary of both papers. Here are the ones for OC22 -
Based on what you have told me, I have created a code to get the adsorption energy with CO on a Pt slab.
If there are any mistakes, please correct or let me know.
# import
import numpy as np
from ase import Atoms
from ase.build import fcc111, add_adsorbate
from ase.constraints import FixAtoms
from ase.build import fcc111, molecule, add_adsorbate
from ase.optimize import LBFGS
from ocpmodels.common.relaxation.ase_utils import OCPCalculator
# calculator setting
!wget -q https://dl.fbaipublicfiles.com/opencatalystproject/models/2022_09/oc22/s2ef/gnoc_oc22_oc20_all_s2ef.pt
checkpoint_path = "/content/ocp/gnoc_oc22_oc20_all_s2ef.pt"
config_yml_path = "configs/oc22/s2ef/gemnet-oc/gemnet_oc_oc20_oc22.yml"
calculator = OCPCalculator(config_yml=config_yml_path, checkpoint=checkpoint_path)
# slab(Pt)
slab = fcc111("Pt", size=(4, 4, 4), vacuum=40.0, periodic=True)
slab.calc = calculator
opt = LBFGS(slab)
opt.run(fmax=0.01, steps=100)
E_slab = slab.get_potential_energy()
# gas(CO)
E_gas = (-7.332)+(-7.459)
# slab+gas(Pt + CO)
adslab = fcc111("Pt", size=(4, 4, 4))
adsorbate = molecule("CO")
add_adsorbate(adslab, adsorbate, 3, "bridge")
tags = np.zeros(len(adslab))
tags[48:64] = 1
tags[64:] = 2
adslab.set_tags(tags)
cons= FixAtoms(indices=[atom.index for atom in adslab if (atom.tag == 0)])
adslab.set_constraint(cons)
adslab.center(vacuum=40.0, axis=2)
adslab.set_pbc(True)
adslab.calc = calculator
opt = LBFGS(adslab)
opt.run(fmax=0.01, steps=100)
E_slab_gas = adslab.get_potential_energy()
# calculate E_adsorp
E_adsorp = E_slab_gas - (E_slab + E_gas)
print(f"E_adsorp {E_adsorp}, E_slab_gas {E_slab_gas}, E_slab {E_slab}, E_gas {E_gas}")
The logic looks fine to me. Few minor details to keep in mind to get improved accuracies and/or to stay more consistent with OC20:
The functional used for OC20 and OC22 were different. OC20 was RPBE and OC22 PBE+U. This leads to slightly different gas phase atomic contributions. In order to get the most accurate results, since your system is similar to OC20 systems (and if you want it to be consistent with RPBE), you should use atomic contribution from the OC20 paper.
For relaxations, to stay a little more consistent with DFT settings, you could keep the fmax at 0.03 and steps to 200.
The vacuum layer of 40 \AA is on the higher end of what was used in OC20 ( >= 20 \AA) but this shouldn't cause high inaccuracies.
If loading the gemnet-OC OC20+OC22 checkpoint from https://dl.fbaipublicfiles.com/opencatalystproject/models/2022_09/oc22/s2ef/gnoc_oc22_oc20_all_s2ef.pt (and maybe others) and using it for a gas-phase relaxation:
there is a RunetimeError in the spherical basis function:
Other checkpoints seem to run fine. For example using the gemnet-t checkpoint
gemnet_t_direct_h512_all.pt
works fine:and yields