Source code for asaplib.hypers.symfun_gen

#!/usr/bin/python
import sys
import argparse
import numpy as np
from asaplib.hypers.univeral_length_scales import uni_length_scales, system_pair_bond_lengths

"""
Automatically generate the hyperparameters of ACSF descriptors for arbitrary elements and combinations.

## Example
The command
gen_universal_soap_hypers.py --Zs 1

generates ACSF for hydrogen
"""

[docs]def main(Zs, scalerange, sharpness): """ scalerange: type=float, scale the cutoffs of the SFs. sharpness: type=float, sharpness factor for atom_width, default=1.0, larger sharpness means more resolution, and more SFs will be generated. rmin: type=float, distance in Angstrom to the first nearest neighbor. Eliminates the symmetry functions that investigate the space between 0 and rmin. """ for Z in Zs: if str(Z) not in uni_length_scales: raise RuntimeError("key Z {} not present in length_scales table".format(Z)) shortest_bond, longest_bond = system_pair_bond_lengths(Zs, uni_length_scales) cutoff = longest_bond * 1.56 * float(scalerange) rmin = shortest_bond N = min(int(sharpness*(cutoff-rmin)/0.5), 5) index = np.arange(N+1, dtype=float) shift_array = cutoff*(1./N)**(index/(len(index)-1)) eta_array = 1./shift_array**2. for fel in Zs: for sel in Zs: print("# symfunctions for type %s 2 %s" %(fel, sel)) for eta in eta_array: if 3*np.sqrt(1/eta) > rmin: print("symfunction_short %s 2 %s %.4f 0.000 %.3f" %(fel, sel, eta, cutoff)) for i in range(len(shift_array)-1): eta = 1./((shift_array[N-i] - shift_array[N-i-1])**2) if shift_array[N-i] + 3*np.sqrt(1/eta) > rmin: print("symfunction_short %s 2 %s %.4f %.3f %.3f" %(fel, sel, eta, shift_array[N-i], cutoff)) eta_array = np.logspace(-3,0,N//2) zeta_array = [1.000, 4.000, 16.000] for fel in Zs: ang_Zs = list(Zs) for sel in Zs: for tel in ang_Zs: print("# symfunctions for type %s 3 %s %s" %(fel, sel, tel)) for eta in eta_array: for zeta in zeta_array: if 3*np.sqrt(1/eta) > rmin: print("symfunction_short %s 3 %s %s %.4f 1.000 %.3f %.3f" %(fel, sel, tel, eta, zeta, cutoff)) print("symfunction_short %s 3 %s %s %.4f -1.000 %.3f %.3f" %(fel, sel, tel, eta, zeta, cutoff)) ang_Zs.pop(0)
if __name__ == "__main__": parser = argparse.ArgumentParser(description=None) parser.add_argument("--Zs", nargs="+", type=int, help="atomic numbers to calculate descriptors for", required=True) parser.add_argument('-sr', '--scalerange', type = float, default = 1.0, help = 'Scale the length scales.') parser.add_argument('-s', '--sharpness', type = float, default = 1.0, help = 'larger means more ACSFs will be selected.') args = parser.parse_args() main(args.Zs, args.scalerange, args.sharpness)