Changing model parameters in ASE

Hi all,

I am interested in modifying the parameters of a KIM model - e.g. “SW_StillingerWeber_1985_Si__MO_405512056662_005” - and performing some calculations using ASE within a Jupyter notebook.

Using the KimPy interface I can create a kimpy.model.Model object, with which I can see the number, type and value of the different parameters, and I can also set their values within this object.

My question is, how can I feed these changes to the parameters through to an ASE calculator?

Apologies if this is a simple question / if this is the wrong way to approach this problem, but I am still fairly new to OpenKIM !

Thanks in advance,
Iain

Hi Iain,

Efforts are already underway: https://gitlab.com/ase/ase/-/merge_requests/2267. We’re still hashing out the interface, but if you check out the latest commit on our fork, you can do something like this:

import pprint

from ase import Atoms
from ase.calculators.kim import KIM

pp = pprint.PrettyPrinter(indent=4)

calc = KIM("SW_StillingerWeber_1985_Si__MO_405512056662_005")

# Print summary of model parameters, including their length and how they're indexed
pp.pprint(calc.parameters_metadata())
print()

atoms = Atoms("Si" * 2, positions=[[0, 0, 0], [0, 0, 2.1]])
atoms.calc = calc

energy_orig = atoms.get_potential_energy()
print(f"Energy with original parameters = {energy_orig} eV")

# Now double the parameter A
A_orig = calc.get_parameters(A=[0])['A'][1][0]
A_modified = 2 * A_orig

calc.set_parameters(A=[0, A_modified])

energy_modified = atoms.get_potential_energy()
print(f"Energy with modified parameters = {energy_modified} eV")

Dan

Hi again Iain,

Just wanted to leave a note here that the merge request mentioned above has been merged into the master branch of ASE and will be part of the next official release. The docs page for the KIM calculator won’t be updated until then, so I’ll echo the part about changing parameters here:

If one instantiates the calculator for a KIM Portable Model that registers its parameters, they can be accessed or mutated using the get_parameters and set_parameters methods. For example, to print the components of the parameters epsilons and sigmas in the Lennard-Jones universal model corresponding to Mo-Mo (index 4879), Mo-S (index 2006) and S-S (index 1980) interactions, one can do the following:

model = "LJ_ElliottAkerson_2015_Universal__MO_959249795837_003"
calc = KIM(model)
print(calc.get_parameters(epsilons=[4879, 2006, 1980],
                          sigmas=[4879, 2006, 1980])

This will print a dictionary whose keys are the parameter names and whose values are lists that each contain two sublists. The first contains the set of indices in the parameters arrays that were requested and the second contains the corresponding parameter values:

{'epsilons': [[4879, 2006, 1980],
              [4.47499, 4.421814057295943, 4.36927]],
 'sigmas': [[4879, 2006, 1980],
            [2.74397, 2.30743, 1.87089]]}

Or, suppose we want to set the values of the components of the epsilons parameter of the same model corresponding to Mo-Mo, Mo-S, and S-S to 5.0, 4.5, and 4.0, respectively. In this case, a syntax similar is used:

model = "LJ_ElliottAkerson_2015_Universal__MO_959249795837_003"
calc = KIM(model)
calc.set_parameters(epsilons=[[4879, 2006, 1980],
                              [5.0, 4.5, 4.0]])

Note: For models with parameter arrays that contain many components, such as the Lennard-Jones universal model above, one must refer to the documentation of the model itself (or its model driver, if it uses one) in order to ascertain the meaning of the different components of the parameter arrays.

Let me know if you have any questions,
Dan