def num_grad(elems, coords, basis_set, dr=0.001): grad = np.zeros_like(coords) for i_atom in range(len(grad)): for i_xyz in range(3): coords[i_atom, i_xyz] += dr e_p = one_e_qyd.solve_one_e(elems, coords, basis_set, verbose=False) coords[i_atom, i_xyz] -= dr * 2 e_m = one_e_qyd.solve_one_e(elems, coords, basis_set, verbose=False) coords[i_atom, i_xyz] += dr grad[i_atom, i_xyz] = (e_p - e_m) / dr / 2 return grad
def optimize_coords(elems, coords, basis_set, max_iter=100, filename=None): dr = 0.001 step_length = 0.1 print("--== Optimization start! ==--") last_e = 0 for i in xrange(max_iter): print("\n*** Iteration %d ***\n" % i) e = one_e_qyd.solve_one_e(elems, coords, basis_set, verbose=False) print("Energy = %13.7f Eh" % e) grad = num_grad(elems, coords, basis_set) g_norm = np.sqrt(np.mean(grad**2)) print("Grad norm = %13.7f" % g_norm) coords -= grad / g_norm * step_length print("New Coordinates") print(coords) if g_norm < 1e-7: print("Optimization Finished!") if filename is not None: one_e_qyd.write_xyz(elems, coords, filename) return if e > last_e: step_length /= 2 last_e = e print("Optimization not finished in %d steps." % max_iter)
import numpy as np import one_e_qyd import matplotlib.pyplot as plt plt.style.use('ggplot') elems = ['H', 'H'] coords = np.array([[0, 0, 0], [0, 0, 1.4]]) for basis in ['sto-3g', '3-21g', '6-311g']: basis_set = one_e_qyd.load_basis(basis) d_range = np.linspace(0.5, 10.0, num=96) results = [] for d in d_range: #print("Dist = %.3f Bohr" % d) coords[1][-1] = d energy = one_e_qyd.solve_one_e(elems, coords, basis_set, verbose=False) #print("Total Energy = %.7f "%energy) results.append(energy) plt.plot(d_range, results, lw=1.5, label=basis) plt.legend() plt.xlabel("H-H Dist (Bohr)") plt.ylabel("Total Energy (Eh)") plt.title("Scan of H2+ PES") plt.savefig("scan_H2.pdf") plt.close() print results