def test_ext_params(): func = pylibxc.LibXCFunctional(1, 1) assert 0 == len(func.get_ext_param_descriptions()) assert 0 == len(func.get_ext_param_default_values()) func.set_dens_threshold(1.e-16) func.set_dens_threshold(5) with pytest.raises(ValueError): func.set_ext_params([]) func = pylibxc.LibXCFunctional("XC_HYB_GGA_XC_HSE06", 1) assert 3 == len(func.get_ext_param_descriptions()) assert 3 == len(func.get_ext_param_default_values()) assert all("param" in x for x in func.get_ext_param_descriptions()) func.set_dens_threshold(1.e-16) func.set_dens_threshold(5) # Segfaults, need to check it out func.set_ext_params([5, 3, 3]) with pytest.raises(ValueError): func.set_ext_params([5, 3]) with pytest.raises(ValueError): func.set_dens_threshold(-1)
def test_mgga_lapl_compute(polar): # Build input ndim = _size_tuples[polar] inp = {} inp["rho"] = np.random.random((compute_test_dim * ndim[0])) inp["sigma"] = np.random.random((compute_test_dim * ndim[1])) inp["tau"] = np.random.random((compute_test_dim * ndim[3])) inp["lapl"] = np.random.random((compute_test_dim * ndim[3])) # Compute func = pylibxc.LibXCFunctional("mgga_x_br89", polar) # Test consistency ret_ev = func.compute(inp, do_exc=True, do_vxc=True) ret_e = func.compute(inp, do_exc=True, do_vxc=False) ret_v = func.compute(inp, do_exc=False, do_vxc=True) assert ret_ev["zk"].size == compute_test_dim assert ret_ev["vrho"].size == compute_test_dim * ndim[0] assert ret_ev["vsigma"].size == compute_test_dim * ndim[1] assert _dict_array_comp(ret_ev, ret_e, ["zk"]) assert _dict_array_comp(ret_ev, ret_v, ["vrho", "vsigma", "vtau"]) # Test exception del inp["lapl"] with pytest.raises(KeyError): func.compute(inp, do_exc=True, do_vxc=True)
def test_lda_compute(polar): # Build input ndim = _size_tuples[polar] inp = {} inp["rho"] = np.random.random((compute_test_dim * ndim[0])) func = pylibxc.LibXCFunctional("lda_c_vwn", polar) # Compute ret_full = func.compute(inp, do_exc=True, do_vxc=True, do_fxc=True, do_kxc=True) ret_ev = func.compute(inp, do_exc=True, do_vxc=True, do_fxc=False, do_kxc=False) ret_e = func.compute(inp, do_exc=True, do_vxc=False, do_fxc=False, do_kxc=False) ret_v = func.compute(inp, do_exc=False, do_vxc=True, do_fxc=False, do_kxc=False) ret_f = func.compute(inp, do_exc=False, do_vxc=False, do_fxc=True, do_kxc=False) ret_k = func.compute(inp, do_exc=False, do_vxc=False, do_fxc=False, do_kxc=True) # Test consistency assert ret_full["zk"].size == compute_test_dim assert ret_full["vrho"].size == compute_test_dim * ndim[0] assert np.allclose(ret_full["zk"], ret_ev["zk"]) assert np.allclose(ret_full["vrho"], ret_ev["vrho"]) assert np.allclose(ret_full["zk"], ret_e["zk"]) assert np.allclose(ret_full["vrho"], ret_v["vrho"]) assert np.allclose(ret_full["v2rho2"], ret_f["v2rho2"]) assert np.allclose(ret_full["v3rho3"], ret_k["v3rho3"])
def get_libxc(name: str) -> BaseXC: """ Get the XC object of the libxc based on its libxc's name. Arguments --------- name: str The full libxc name, e.g. "lda_c_pw" Returns ------- BaseXC XC object that wraps the xc requested """ obj = pylibxc.LibXCFunctional(name, "unpolarized") family = obj.get_family() del obj if family == 1: # LDA return LibXCLDA(name) elif family == 2: # GGA return LibXCGGA(name) elif family == 4: # MGGA return LibXCMGGA(name) else: raise NotImplementedError( "LibXC wrapper for family %d has not been implemented" % family)
def test_gga_compute(polar): # Build input ndim = _size_tuples[polar] inp = {} inp["rho"] = np.random.random((compute_test_dim * ndim[0])) inp["sigma"] = np.random.random((compute_test_dim * ndim[1])) # Compute func = pylibxc.LibXCFunctional("gga_c_pbe", polar) ret_full = func.compute(inp, do_exc=True, do_vxc=True, do_fxc=True, do_kxc=True) ret_ev = func.compute(inp, do_exc=True, do_vxc=True, do_fxc=False, do_kxc=False) ret_e = func.compute(inp, do_exc=True, do_vxc=False, do_fxc=False, do_kxc=False) ret_v = func.compute(inp, do_exc=False, do_vxc=True, do_fxc=False, do_kxc=False) ret_f = func.compute(inp, do_exc=False, do_vxc=False, do_fxc=True, do_kxc=False) ret_k = func.compute(inp, do_exc=False, do_vxc=False, do_fxc=False, do_kxc=True) # Test consistency assert ret_full["zk"].size == compute_test_dim assert ret_full["vrho"].size == compute_test_dim * ndim[0] assert ret_full["vsigma"].size == compute_test_dim * ndim[1] assert _dict_array_comp(ret_full, ret_ev, ["zk", "vrho", "vsigma"]) assert _dict_array_comp(ret_full, ret_e, ["zk"]) assert _dict_array_comp(ret_full, ret_v, ["vrho", "vsigma"]) assert _dict_array_comp(ret_full, ret_f, ["v2rho2", "v2rhosigma", "v2sigma2"]) assert _dict_array_comp(ret_full, ret_k, ["v3rho3", "v3rho2sigma", "v3rhosigma2", "v3sigma3"])
def __init__(self, xc_name_in): self.mini = 1e-90 self._xGGA, self._cGGA, self._xcGGA = False, False, False xc_name = translate_xc(xc_name_in) self._sep_xc = (',' in xc_name) if self._sep_xc: [x_name, c_name] = xc_name.split(',') self._pylibxc_x = pylibxc.LibXCFunctional(x_name, "unpolarized") self._pylibxc_c = pylibxc.LibXCFunctional(c_name, "unpolarized") self._xGGA = (self._pylibxc_x.get_family() in _ggaIDs) self._cGGA = (self._pylibxc_c.get_family() in _ggaIDs) else: self._pylibxc_xc = pylibxc.LibXCFunctional(xc_name, "unpolarized") self._xcGGA = (self._pylibxc_xc.get_family() in _ggaIDs) self._anyGGA = any([self._xGGA, self._cGGA, self._xcGGA])
def test_deriv_flags(polar): func = pylibxc.LibXCFunctional("mgga_c_tpss", polar) ndim = _size_tuples[polar] inp = {} inp["rho"] = np.random.random((compute_test_dim * ndim[0])) inp["sigma"] = np.random.random((compute_test_dim * ndim[1])) inp["tau"] = np.random.random((compute_test_dim * ndim[3])) inp["lapl"] = np.random.random((compute_test_dim * ndim[3]))
def test_hyb_getters(): func = pylibxc.LibXCFunctional("hyb_gga_xc_b3lyp", "unpolarized") assert pytest.approx(0.2) == func.get_hyb_exx_coef() with pytest.raises(ValueError): func.get_cam_coef() with pytest.raises(ValueError): func.get_vv10_coef()
def set_xc_func(xc_code): # when xc code is one of the special avatom defined functionals if xc_code in xc_special_codes: xc_func = XCFunc(xc_code) err = 0 else: # whether the xc functional is spin polarized if config.spindims == 2: xc_func = pylibxc.LibXCFunctional(xc_code, "polarized") else: xc_func = pylibxc.LibXCFunctional(xc_code, "unpolarized") # initialize the temperature if required xc_temp_funcs = ["lda_xc_gdsmfb", "lda_xc_ksdt", 577, 259] if xc_code in xc_temp_funcs: xc_func.set_ext_params([config.temp]) return xc_func
def test_cam_getters(): func = pylibxc.LibXCFunctional("hyb_gga_xc_cam_b3lyp", "unpolarized") assert pytest.approx(0.65) == func.get_hyb_exx_coef() omega, alpha, beta = func.get_cam_coef() assert pytest.approx(0.33) == omega assert pytest.approx(0.65) == alpha assert pytest.approx(-0.46) == beta with pytest.raises(ValueError): func.get_vv10_coef()
def test_libxc_functional_info(): func = pylibxc.LibXCFunctional(1, 1) assert func.get_number() == 1 assert func.get_kind() == 0 assert func.get_name() == "Slater exchange" assert func.get_family() == 1 assert func.get_flags() == 143 assert len(func.get_bibtex()) == 2 assert len(func.get_references()) == 2 assert len(func.get_doi()) == 2 func = pylibxc.LibXCFunctional("XC_HYB_MGGA_XC_WB97M_V", 1) assert func.get_number() == 531 assert func.get_kind() == 2 assert func.get_name() == "wB97M-V exchange-correlation functional" assert func.get_family() == 64 assert func.get_flags() == 1411 assert len(func.get_bibtex()) == 1 assert len(func.get_references()) == 1 assert len(func.get_doi()) == 1
def test_vv10_getters(): func = pylibxc.LibXCFunctional("gga_xc_vv10", "unpolarized") b, C = func.get_vv10_coef() assert pytest.approx(5.9) == b assert pytest.approx(0.0093) == C with pytest.raises(ValueError): func.get_cam_coef() with pytest.raises(ValueError): func.get_hyb_exx_coef()
def test_deriv_flags(polar): func = pylibxc.LibXCFunctional("mgga_c_tpss", polar) ndim = _size_tuples[polar] inp = {} inp["rho"] = np.random.random((compute_test_dim * ndim[0])) inp["sigma"] = np.random.random((compute_test_dim * ndim[1])) inp["tau"] = np.random.random((compute_test_dim * ndim[3])) inp["lapl"] = np.random.random((compute_test_dim * ndim[3])) with pytest.raises(ValueError): func.compute(inp, do_fxc=True) with pytest.raises(ValueError): func.compute(inp, do_fxc=True)
def test_libxc_functional_build(): pylibxc.LibXCFunctional(1, 1) pylibxc.LibXCFunctional(1, 2) pylibxc.LibXCFunctional("XC_LDA_C_VWN", "polarized") pylibxc.LibXCFunctional("lda_c_vwn", "unpolarized") # Check functional edge cases with pytest.raises(KeyError): pylibxc.LibXCFunctional("something", 1) with pytest.raises(KeyError): pylibxc.LibXCFunctional(5000, 1) # Check spin edge cases with pytest.raises(KeyError): pylibxc.LibXCFunctional("lda_c_vwn", 10) with pytest.raises(KeyError): pylibxc.LibXCFunctional("lda_c_vwn", "something")
def check_xc_func(xc_code, id_supp): """ Checks there is a valid libxc code (or "None" for no x/c term) Then initializes the libxc object Inputs: - xc_code (str / int) : the name or id of the libxc functional - id_supp (int) : list of supported xc family ids Returns: - xc_func (object / int) : the xc functional object from libxc (or 0) - err (int) : the error code """ # check the xc code is either a string descriptor or integer id if isinstance(xc_code, (str, int)) == False: err = 1 xc_func_id = 0 # when xc code is one of the special avatom defined functionals if xc_code in xc_special_codes: xc_func_name = xc_code err = 0 # make the libxc object functional else: # checks if the libxc code is recognised try: xc_func = pylibxc.LibXCFunctional(xc_code, "unpolarized") # check the xc family is supported if xc_func._family in id_supp: err = 0 else: err = 3 xc_func = 0 except KeyError: err = 2 xc_func = 0 xc_func_name = xc_func._xc_func_name return xc_func_name, err
def testxc(): import pylibxc f = open('neighs.txt', 'rb') neighs = pickle.load(f) f.close() f = open('dNh.txt', 'rb') (d, N, h) = pickle.load(f) f.close() f = open('nc.txt', 'rb') nc = pickle.load(f) f.close() f = open('nv.txt', 'rb') nv = pickle.load(f) f.close() n = nc + nv grads, sigmas = pro.densitygradient(N, h, neighs, n) ## func = pylibxc.LibXCFunctional("GGA_XC_PBE", "unpolarized") ## inp = {'rho': n, 'sigma': sigmas} ## ret = func.compute(inp) ## zk = ret['zk'][0] ## vrho = ret['vrho'][0] ## vsigmas = ret['vsigma'][0] ## tmp = {} ## for i in range(N): ## tmp[i] = vsigmas[i]*grads[i] ## vxc = np.zeros(N) ## for i in range(N): ## tmpres = 0.0 ## for ax in range(3): ## lval = tmp[neighs[i][ax][0]][ax] ## rval = tmp[neighs[i][ax][1]][ax] ## tmpres += pro.centraldifference(lval, rval, h[ax]) ## vxc[i] = zk[i]+vrho[i]-2*tmpres ## print(min(vxc), max(vxc), la.norm(vxc)) func = pylibxc.LibXCFunctional("LDA_XC_KSDT", "unpolarized") inp = {'rho': n} ret = func.compute(inp) zk = ret['zk'][0] vrho = ret['vrho'][0] vxc = np.zeros(N) for i in range(N): vxc[i] = zk[i] + vrho[i] print(sum(vxc), max(vxc), min(vxc))
def xcpotential(N, h, neighs, n): logger.info('Entered') grads, sigmas = densitygradient(N, h, neighs, n) func = pylibxc.LibXCFunctional("GGA_XC_PBE1W", "unpolarized") inp = {'rho': n, 'sigma': sigmas} ret = func.compute(inp) vrho = ret['vrho'][0] vsigmas = ret['vsigma'][0] tmp = {} for i in range(N): tmp[i] = vsigmas[i] * grads[i] vxc = np.zeros(N) for i in range(N): tmpres = 0.0 for ax in range(3): lval = tmp[neighs[i][ax][0]][ax] rval = tmp[neighs[i][ax][1]][ax] tmpres += centraldifference(lval, rval, h[ax]) vxc[i] = vrho[i] - 2 * tmpres logger.info('Exiting') return vxc
] molgrid = MolGrid(molecule_at_grid, molecule.atnums) alc_lda = Alchemical_tools( basis, molecule, point_charge_positions=R, point_charges_values=q, coord_type="cartesian", k="lda_x", molgrid=molgrid, ) two_electron_int = electron_repulsion_integral(basis, transform=molecule.mo.coeffs.T, coord_type="cartesian", notation="chemist") xc_function = pylibxc.LibXCFunctional("lda_x", "polarized") a_dm = np.dot(molecule.mo.coeffsa * molecule.mo.occsa, molecule.mo.coeffsa.T.conj()) b_dm = np.dot(molecule.mo.coeffsb * molecule.mo.occsb, molecule.mo.coeffsb.T.conj()) a_density_values = evaluate_density(a_dm, basis, molgrid.points, coord_type="cartesian") b_density_values = evaluate_density(b_dm, basis, molgrid.points, coord_type="cartesian") inp = {"rho": np.array([a_density_values, b_density_values])} inp["rho"] = inp["rho"].transpose().reshape(len(inp["rho"][0]) * 2) f_xc_values = (xc_function.compute(inp, None, False, False, True,
def __init__(self, name: str) -> None: self.libxc_unpol = pylibxc.LibXCFunctional(name, "unpolarized") self.libxc_pol = pylibxc.LibXCFunctional(name, "polarized")
def test_K_matrices_K_fxc_DFT(): xc_function = pylibxc.LibXCFunctional("lda_x", "polarized") a_dm = np.dot(molecule.mo.coeffsa * molecule.mo.occsa, molecule.mo.coeffsa.T.conj()) b_dm = np.dot(molecule.mo.coeffsb * molecule.mo.occsb, molecule.mo.coeffsb.T.conj()) a_density_values = evaluate_density(a_dm, basis, molgrid.points, coord_type="cartesian") b_density_values = evaluate_density(b_dm, basis, molgrid.points, coord_type="cartesian") inp = {"rho": np.array([a_density_values, b_density_values])} inp["rho"] = inp["rho"].transpose().reshape(len(inp["rho"][0]) * 2) f_xc_values = (xc_function.compute(inp, None, False, False, True, False))["v2rho2"] f_xc_values = np.array([ f_xc_values.reshape(len(f_xc_values[0]), 3)[:, 0], f_xc_values.reshape(len(f_xc_values[0]), 3)[:, 1], f_xc_values.reshape(len(f_xc_values[0]), 3)[:, 2], ]) del (a_dm, b_dm, a_density_values, b_density_values, xc_function, inp) MO_values = evaluate_basis(basis, molgrid.points, transform=molecule.mo.coeffs.T, coord_type="cartesian") MO_values_conjugated = np.conjugate(MO_values) indices = (occupied_ind, virtual_ind) K_size = len(occupied_ind[0]) * len(virtual_ind[0]) + len( occupied_ind[1]) * len(virtual_ind[1]) K_shape = [K_size, K_size] K_fxc_DFT = np.zeros(K_shape, float) for t in range(2): for j_c, j in enumerate(indices[0][t]): for b_c, b in enumerate(indices[1][t]): jbt = (t * len(indices[0][0]) * len(indices[1][0]) + j_c * len(indices[1][t]) + b_c) for s in range(2): for i_c, i in enumerate(indices[0][s]): for a_c, a in enumerate(indices[1][s]): ias = ( s * len(indices[0][0]) * len(indices[1][0]) + i_c * len(indices[1][s]) + a_c) values = (f_xc_values[s + t] * MO_values_conjugated[i] * MO_values[a] * MO_values_conjugated[j] * MO_values[b]) K_fxc_DFT[ias][jbt] = K_fxc_DFT[ias][ jbt] + molgrid.integrate(values) K_fxc_DFT = np.array([ K_fxc_DFT[:70, :70], K_fxc_DFT[:70, 70:], K_fxc_DFT[70:, :70], K_fxc_DFT[70:, 70:], ]) assert np.allclose( K_mats.K_fxc_DFT(XC_functional="lda_x", molgrid=molgrid), K_fxc_DFT) K_shape = [1, K_size] K_fxc_DFT = np.zeros(K_shape, float) index = [[4], []] indices = (occupied_ind, virtual_ind, index) for t in range(2): for j_c, j in enumerate(indices[0][t]): for b_c, b in enumerate(indices[1][t]): jbt = (t * len(indices[0][0]) * len(indices[1][0]) + j_c * len(indices[1][t]) + b_c) for s in range(2): for f_c, f in enumerate(indices[2][s]): ffs = s * len(indices[2][0]) + f_c values = (f_xc_values[s + t] * MO_values_conjugated[f] * MO_values[f] * MO_values_conjugated[j] * MO_values[b]) K_fxc_DFT[ffs][jbt] = K_fxc_DFT[ffs][ jbt] + molgrid.integrate(values) K_fxc_DFT_0 = K_mats.K_fxc_DFT(shape="line", index=index, XC_functional="lda_x", molgrid=molgrid) assert np.allclose(K_fxc_DFT_0[0], K_fxc_DFT[0, :70]) assert np.allclose(K_fxc_DFT_0[1], K_fxc_DFT[0, 70:]) assert np.allclose(K_fxc_DFT_0[2], np.zeros([0, 70])) assert np.allclose(K_fxc_DFT_0[3], np.zeros([0, 70])) values = (f_xc_values[0] * MO_values_conjugated[4] * MO_values[4] * MO_values_conjugated[4] * MO_values[4]) K_fxc_DFT = molgrid.integrate(values) assert np.allclose( K_mats.K_fxc_DFT(shape="point", index=[[4, 4], []], XC_functional="lda_x", molgrid=molgrid), K_fxc_DFT, )
def test_M_matrix_calculate_M(): xc_function = pylibxc.LibXCFunctional("lda_x", "polarized") a_dm = np.dot(molecule.mo.coeffsa * molecule.mo.occsa, molecule.mo.coeffsa.T.conj()) b_dm = np.dot(molecule.mo.coeffsb * molecule.mo.occsb, molecule.mo.coeffsb.T.conj()) a_density_values = evaluate_density(a_dm, basis, molgrid.points, coord_type="cartesian") b_density_values = evaluate_density(b_dm, basis, molgrid.points, coord_type="cartesian") inp = {"rho": np.array([a_density_values, b_density_values])} inp["rho"] = inp["rho"].transpose().reshape(len(inp["rho"][0]) * 2) f_xc_values = (xc_function.compute(inp, None, False, False, True, False))["v2rho2"] f_xc_values = np.array([ f_xc_values.reshape(len(f_xc_values[0]), 3)[:, 0], f_xc_values.reshape(len(f_xc_values[0]), 3)[:, 1], f_xc_values.reshape(len(f_xc_values[0]), 3)[:, 2], ]) del (a_dm, b_dm, a_density_values, b_density_values, xc_function, inp) MO_values = evaluate_basis(basis, molgrid.points, transform=molecule.mo.coeffs.T, coord_type="cartesian") MO_values_conjugated = np.conjugate(MO_values) occupied_ind = [[], []] virtual_ind = [[], []] for i in range(len(molecule.mo.occsa)): if molecule.mo.occsa[i] - 1 == 0: occupied_ind[0] = occupied_ind[0] + [i] if molecule.mo.occsa[i] == 0: virtual_ind[0] = virtual_ind[0] + [i] for i in range(len(molecule.mo.occsb)): if molecule.mo.occsb[i] - 1 == 0: occupied_ind[1] = occupied_ind[1] + [i + molecule.mo.nbasis] if molecule.mo.occsb[i] == 0: virtual_ind[1] = virtual_ind[1] + [i + molecule.mo.nbasis] indices = (occupied_ind, virtual_ind) M_HF = np.zeros([140, 140], float) M_LDA = np.zeros([140, 140], float) for s in range(2): for i_c, i in enumerate(indices[0][s]): for a_c, a in enumerate(indices[1][s]): ias = (s * len(indices[0][0]) * len(indices[1][0]) + i_c * len(indices[1][s]) + a_c) for t in range(2): for j_c, j in enumerate(indices[0][t]): for b_c, b in enumerate(indices[1][t]): jbt = ( t * len(indices[0][0]) * len(indices[1][0]) + j_c * len(indices[1][t]) + b_c) M_HF[ias][jbt] = (M_HF[ias][jbt] + 2 * two_electron_int[i, a, j, b]) M_LDA[ias][jbt] = ( M_LDA[ias][jbt] + 2 * two_electron_int[i, a, j, b]) values = (f_xc_values[s + t] * MO_values_conjugated[i] * MO_values[a] * MO_values_conjugated[j] * MO_values[b]) M_LDA[ias][jbt] = M_LDA[ias][ jbt] + 2 * molgrid.integrate(values) if s == t: M_HF[ias][jbt] = ( M_HF[ias][jbt] - 2 * two_electron_int[i, a, j, b]) if s == t and i == j and a == b: M_HF[ias][jbt] = (M_HF[ias][jbt] + molecule.mo.energies[a] - molecule.mo.energies[i]) M_LDA[ias][jbt] = (M_LDA[ias][jbt] + molecule.mo.energies[a] - molecule.mo.energies[i]) assert np.allclose(M_mat.calculate_M(k="HF", complex=False), M_HF) assert np.allclose( M_mat.calculate_M(k="lda_x", complex=False, molgrid=molgrid), M_LDA)
# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import os import sys ldpath = os.path.abspath( os.path.join(__file__, '..', '..', 'lib', 'deps', 'lib')) if ldpath not in os.environ['LD_LIBRARY_PATH']: sys.stderr.write(f'Set\n\tLD_LIBRARY_PATH={ldpath}:$LD_LIBRARY_PATH\n' 'and rerun the script\n') exit() pypath = os.path.join(__file__, '..', '..', 'lib', 'build', 'deps', 'src', 'libxc') sys.path.insert(0, os.path.abspath(pypath)) import pylibxc for xcname in pylibxc.util.xc_available_functional_names(): f = pylibxc.LibXCFunctional(xcname, 1) f_id = f.get_number() ref = f.get_references() key = f"'{xcname.upper()}'" print(f"{key:<31s}: {f_id:<3d}, # {ref[0]}") for r in ref[1:]: print(f" # {r}")
def K_fxc_DFT(self, molgrid, Type=1, XC_functional="lda_x", shape="square", index=None): """Calculate the exchange-correlation part of the coupling matrix K Parameters ---------- molgrid : MolGrid class object (from grid package) suitable for numerical integration of any real space function related to the molecule (such as the density) Type : int, 1 or 2, in cassee of real molecular orbitals, type1 = type2 XC_functionl : str Code name of the exchange correlation functional as given on the page: https://tddft.org/programs/libxc/functionals/ shape: str; 'square', 'rectangle', 'line' or 'point', default is 'square' If shape == 'square', generate (K_fxc_DFT)ias,jbt Useful to generate the M matrices If shape == 'line' , generate (K_fxc_DFT)ffs,jbt Useful to generate the fukui matrices and hardness If shape == 'point' generate (K_fxc_DFT)ffs,ffs Useful to generate the hardness index: None or list of two list of int, default is None Necessary if shape == 'line' or shape == 'point' If index is a list of two list of integers, it must be like [ l1, l2] with l1 in |[0; molecule.mo.nbasis|[ and l2 in |[molecule.mo.nbasis, 2 * molecule.mo.nbasis|[, (l1 : alpha indices, l2 : beta indices) len(l1) + len(l2) must be equal to 1 if shape is 'line' len(l1) + len(l2) must be equal to 2 if shape is 'point' Return ------ K_fxc_DFT: ndarray [aa_block, ab_block, ba_block, bb_block] if shape == 'square' or 'line' Raises ------ TypeError If 'molgrid' is not a 'MolGrid' instance' If 'Type' is not an int XC_functional is not a str ValueError If 'Type' is not in [1,2] If XC_functional is bot supported by pylibxc (see pylibxc.util.xc_available_functional_names() or https://tddft.org/programs/libxc/functionals/ for the function code spelling) IF XC_functional is not a LDA or a GGA""" if not isinstance(molgrid, MolGrid): raise TypeError("""'molgrid' must be a 'MolGrid' instance""") if not isinstance(Type, int): raise TypeError("""'Type' must be 1 or 2""") if not Type in [1, 2]: raise ValueError("""'Type' must be 1 or 2""") if not isinstance(XC_functional, str): raise TypeError("""'XC_functional' must be a str""") if not XC_functional in pylibxc.util.xc_available_functional_names(): raise ValueError( """"Not suported functionnal, see pylibxc.util.xc_available_functional_names() or the webpage: https://tddft.org/programs/libxc/functionals/""" ) xc_function = pylibxc.LibXCFunctional(XC_functional, "polarized") if not xc_function.get_family() in [1, 2]: raise ValueError( """"Not suported functionnal, only the LDA ans GGAs are supported""" ) # Defining the array of values of fxc(r) suitable for the numerical integration a_dm = np.dot( self._molecule.mo.coeffsa * self._molecule.mo.occsa, self._molecule.mo.coeffsa.T.conj(), ) b_dm = np.dot( self._molecule.mo.coeffsb * self._molecule.mo.occsb, self._molecule.mo.coeffsb.T.conj(), ) a_density_values = evaluate_density(a_dm, self._basis, molgrid.points, coord_type=self._coord_type) b_density_values = evaluate_density(b_dm, self._basis, molgrid.points, coord_type=self._coord_type) inp = {"rho": np.array([a_density_values, b_density_values])} inp["rho"] = inp["rho"].transpose().reshape(len(inp["rho"][0]) * 2) if xc_function.get_family() == 2: a_gradient_density = evaluate_density_gradient( a_dm, self._basis, molgrid.points, coord_type=self._coord_type) b_gradient_density = evaluate_density_gradient( b_dm, self._basis, molgrid.points, coord_type=self._coord_type) inp["sigma"] = np.array([ np.sum(a_gradient_density * a_gradient_density, axis=1), np.sum(a_gradient_density * b_gradient_density, axis=1), np.sum(b_gradient_density * b_gradient_density, axis=1), ]) inp["sigma"] = inp["sigma"].transpose().reshape( len(inp["sigma"][0]) * 3) f_xc_values = (xc_function.compute(inp, None, False, False, True, False))["v2rho2"] f_xc_values = np.array([ f_xc_values.reshape(len(f_xc_values[0]), 3)[:, 0], f_xc_values.reshape(len(f_xc_values[0]), 3)[:, 1], f_xc_values.reshape(len(f_xc_values[0]), 3)[:, 2], ]) if xc_function.get_family() == 2: del (a_gradient_density, b_gradient_density) del (a_dm, b_dm, a_density_values, b_density_values, xc_function, inp) MO_basis_func_val = evaluate_basis( self._basis, molgrid.points, transform=self._molecule.mo.coeffs.T, coord_type=self._coord_type, ) indices = self.K_indices(shape=shape, index=index) # Defining the arrays of values of all the 4 MO products suitable for the numerical integration if shape == "square" or shape == "line": a_occup_val = MO_basis_func_val[indices[0][0]] a_virt_val = MO_basis_func_val[indices[1][0]] kl_a = (a_occup_val[:, None].conj() * a_virt_val).reshape([ a_occup_val.shape[0] * a_virt_val.shape[0], a_virt_val.shape[1] ]) del (a_occup_val, a_virt_val) b_occup_val = MO_basis_func_val[indices[0][1]] b_virt_val = MO_basis_func_val[indices[1][1]] kl_b = (b_occup_val[:, None].conj() * b_virt_val).reshape([ b_occup_val.shape[0] * b_virt_val.shape[0], b_virt_val.shape[1] ]) del (b_occup_val, b_virt_val) klt = np.block([kl_a.T, kl_b.T]).T del kl_b if shape == "line": a_i_values = MO_basis_func_val[indices[2][0]] b_j_values = MO_basis_func_val[indices[2][1]] ij_a = a_i_values.conj() * a_i_values ij_b = b_j_values.conj() * b_j_values ijs = np.block([ij_a.T, ij_b.T]).T del (a_i_values, b_j_values, ij_b) else: ijs = klt ij_a = kl_a del MO_basis_func_val if type == 2: K_fxc_DFT = ijs[:, None] * klt else: K_fxc_DFT = ijs[:, None] * klt.conj() # generate the alpha-alpha block K_fxc_DFT[:ij_a.shape[0], :kl_a.shape[0]] = ( K_fxc_DFT[:ij_a.shape[0], :kl_a.shape[0]] * f_xc_values[0] * molgrid.weights) # generate the beta-alpha block K_fxc_DFT[ij_a.shape[0]:, :kl_a.shape[0]] = ( K_fxc_DFT[ij_a.shape[0]:, :kl_a.shape[0]] * f_xc_values[1] * molgrid.weights) # generate the alpha-beta block K_fxc_DFT[:ij_a.shape[0], kl_a.shape[0]:] = ( K_fxc_DFT[:ij_a.shape[0], kl_a.shape[0]:] * f_xc_values[1] * molgrid.weights) # generate th beta-beta block K_fxc_DFT[ij_a.shape[0]:, kl_a.shape[0]:] = ( K_fxc_DFT[ij_a.shape[0]:, kl_a.shape[0]:] * f_xc_values[2] * molgrid.weights) # integrate K_fxc_DFT = np.sum(K_fxc_DFT / 3, axis=2) K_fxc_DFt = np.array([ K_fxc_DFT[:ij_a.shape[0], :kl_a.shape[0]], K_fxc_DFT[:ij_a.shape[0], kl_a.shape[0]:], K_fxc_DFT[ij_a.shape[0]:, :kl_a.shape[0]], K_fxc_DFT[ij_a.shape[0]:, kl_a.shape[0]:], ]) return K_fxc_DFt else: l = indices[2][0] + indices[2][1] i_values = MO_basis_func_val[l[0]] k_values = MO_basis_func_val[l[1]] K_fxc_DFT = i_values * i_values.conj() * k_values * k_values.conj() if len(indices[2][0]) == 0: return np.sum(K_fxc_DFT * f_xc_values[2] * molgrid.weights / 3) if len(indices[2][0]) == 1: return np.sum(K_fxc_DFT * f_xc_values[1] * molgrid.weights / 3) else: return np.sum(K_fxc_DFT * f_xc_values[0] * molgrid.weights / 3)