-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathatomdb_db.py
115 lines (102 loc) · 4.27 KB
/
atomdb_db.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
r"""
This files generates the results for Table (1) and (2) in the BFit paper.
Specifically, it optimizes the Kullback-Leibler Divergence using the fixed
point iteration method. A normalized Gaussian model is used whose initial
guess is the universal Gaussian basis-set multipled by two. The constraint
that the integral of the model should equal the atomic number is added, via
the attribute `integral_dens`. The attribute `disp` displays the results
at each iteration.
"""
import numpy as np
from atomdb import load
from bfit.fit import KLDivergenceFPI
from bfit.grid import ClenshawRadialGrid
from bfit.model import AtomicGaussianDensity
from bfit.parse_ugbs import get_ugbs_exponents
# change the path to the location of the AtomDB data as needed
DATAPATH = ("/home/ali-tehrani/SoftwareProjects/AtomDBdata",)
results_final = {}
atoms = ["H", "C", "N", "O", "F", "P", "S", "Cl"]
atomic_numbs = [1, 6, 7, 8, 9, 15, 16, 17] # [1 + i for i in range(0, len(atoms))]
mult = [2, 3, 4, 3, 2, 4, 3, 2]
for k, element in enumerate(atoms):
print("Start Atom %s" % element)
# Construct a integration grid
atomic_numb = atomic_numbs[k]
grid = ClenshawRadialGrid(
atomic_numb,
num_core_pts=10000,
num_diffuse_pts=899,
include_origin=True,
# extra_pts=[50,75,100],
)
# Initial Guess constructed from UGBS
ugbs = get_ugbs_exponents(element)
exps_s = ugbs["S"]
num_s = len(exps_s)
exps_p = ugbs["P"]
num_p = len(exps_p)
coeffs = np.array([atomic_numb / (num_s + num_p)] * (num_s + num_p))
e_0 = np.array(exps_s + exps_p) * 2.0
# Construct Atomic Density and Fitting Object
# density = SlaterAtoms(element=element).atomic_density(grid.points)
# Use AtomDB to calculate the density
atom = load(
elem=element,
charge=0,
mult=mult[k],
dataset="hci",
datapath=DATAPATH,
)
dens = atom.dens_func()
density = dens(grid.points)
# plt.plot(grid.points, density, "bo-")
# plt.show()
print(density[-1], grid.points[-1], grid.points[0:3])
density[density < 0.0] = 0.0
# continue
# assert 1 == 0
model = AtomicGaussianDensity(grid.points, num_s=num_s, num_p=num_p, normalize=True)
fit = KLDivergenceFPI(grid, density, model, mask_value=1e-18, spherical=True,
integral_dens=atomic_numb)
# Run the Kullback-Leibler FPI Method
results = fit.run(
coeffs, e_0, maxiter=10000, c_threshold=1e-6, e_threshold=1e-6, d_threshold=1e-14,
disp=True
)
# Construct Fitting Object using SLSQP and optimizing KL
# measure = KLDivergence(mask_value=1e-18)
# fit_KL_slsqp = ScipyFit(grid, density, model, measure=measure, method="SLSQP", spherical=True)
# # Run the SLSQP optimization algorithm
# results = fit_KL_slsqp.run(
# coeffs, e_0, maxiter=10000, disp=True, with_constraint=True, tol=1e-14
# )
print("KL-FPI INFO")
print("-----------")
print("Success %s" % results["success"])
print("Final Coeffs")
print(results["coeffs"])
print("Final Exponents")
print(results["exps"])
print("Integration Value & L1 & L_infinity & LS & KL (With 4 pi r^2 included)")
p = results["performance"][-1]
print(p)
# Calculate the relative errors
spherical = 4.0 * np.pi * grid.points**2.0
l1 = results["performance"][-1][1] / grid.integrate(density * spherical)
linf = results["performance"][-1][2] / np.max(density)
ls = results["performance"][-1][3] / grid.integrate(density**2.0 * spherical)
kl = results["performance"][-1][4] / grid.integrate(
density * np.log(density) * spherical
)
print("Relative Errors L1 & L_infinity & LS & KL (With 4 pi r^2 included)")
print([l1, linf, ls, kl])
# Store the results
results_final[element + "_coeffs_s"] = results["coeffs"][:num_s]
results_final[element + "_exps_s"] = results["exps"][:num_s]
results_final[element + "_coeffs_p"] = results["coeffs"][num_s:]
results_final[element + "_exps_p"] = results["exps"][num_s:]
results_final[element + "_errors_4pir2"] = results["performance"][-1]
results_final[element + "_sucess"] = results["success"]
results_final[element + "_errors"] = [l1, linf, ls, kl]
np.savez("./result_kl_fpi_method_cugbasis_atomdb_hci.npz", **results_final)