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