CInt

Struct CInt 

Source
pub struct CInt {
    pub atm: Vec<[c_int; 6]>,
    pub bas: Vec<[c_int; 8]>,
    pub ecpbas: Vec<[c_int; 8]>,
    pub env: Vec<f64>,
    pub cint_type: CIntType,
}
Expand description

CInt data structure, which contains all the necessary information for GTO electronic integral evaluation, and almost all methods to evaluate GTO electronic integrals for basic usage.

Most users may wish to use the integrate and integrate_spinor methods, which correspond to PySCF’s mol.intor method. We refer to those functions for more documentations.

Please also note column-major and row-major conventions. In most cases, CInt will be column-major. However, for electronic integrals, we also provide row-major functions integrate_row_major and integrate_row_major_spinor. User should be very clear about the memory layout difference.

Also, function eval_gto will evaluate GTO values on grids, which can be utilized in DFT computations.

Documentation and code conventions:

code namedescription
atmatom
basshell
shlshell
aoatomic orbital basis (for users, absolute where starting shell is always the first shell from bas)
cgtoatomic orbital basis (for developers, relative to specified starting shell by shls_slice)
cint, CIntlibcint’s CInt structure or instances
c_intstd::ffi::c_int type (i32 in most cases)

Fields§

§atm: Vec<[c_int; 6]>

Slots of atoms.

Names of this field can be retrieved in cint_ffi.

IndexNameDescriptionRelated getterRelated setter
0CHARGE_OFatomic charge (ECP core electrons excluded)atom_charge
atom_charges
1PTR_COORDcoordinates location (pointer to env field)atom_coord
atom_coords
set_geom
2NUC_MOD_OFnuclear mode of the atomset_nuc_mod
3PTR_ZETApointer to zeta values (pointer to env field)set_rinv_at_nucleus
4PTR_FRAC_CHARGEfractional charge (pointer to env field)atom_charge
atom_charges
5RESERVE_ATMSLOT
6ATM_SLOTS
  • 2 - NUC_MOD_OF can be three kinds:
    • 1 - POINT_NUC point charge, which is the most common case.
    • 2 - GAUSSIAN_NUC nuclear charge is represented by a gaussian distribution, with a zeta value (related to PTR_ZETA).
    • 3 - MM_NUC is a point charge with fractional charge, which is used in molecular mechanics (MM) calculations, with a fractional value (related to PTR_FRAC_CHARGE).
  • 3 - Zeta value is atomic charge that is gaussian-distributed. (NUC_MOD_OF refers to GAUSSIAN_NUC). In other cases, this value should be zero.
§bas: Vec<[c_int; 8]>

Slot of shells (as minimal building block of contracted GTO).

IndexNameDescriptionRelated getter
0ATOM_OF0-based index of corresponding atom
1ANG_OFangular momentumbas_angular
2NPRIM_OFnumber of primitive GTO in basisbas_nprim
3NCTR_OFnumber of contracted GTO in basisbas_nctr
4KAPPA_OFkappa for spinor GTObas_kappa
5PTR_EXPexponents of primitive GTOs (pointer to env field)
6PTR_COEFFcolumn-major contraction coefficients (pointer to env field)
7RESERVE_BASLOT
8BAS_SLOTS
§ecpbas: Vec<[c_int; 8]>

Slot of shells for ECP (effective core potential).

Other entries are the same as bas field, but with some additional:

IndexNameDescription
1ANG_OFangular momentum (refers to angular of $U_L$)
3RADI_POWERnumber of maximum radial power to be summed
4SO_TYPE_OFspin-orb type
§env: Vec<f64>

Slot of floating-point variables.

IndexNameDescriptionRelated getterRelated setter
0PTR_EXPCUTOFFOverall cutoff for integral prescreening, value needs to be ln (threshold)get_integral_screenset_integral_screen
1PTR_COMMON_ORIG$R_C$ (common origin) of $r-R_C$ in dipole, GIAO operatorsget_common_originset_common_origin
4PTR_RINV_ORIG$R_O$ (rinv origin) of $1/(r-R_O)$get_rinv_originset_rinv_origin
7PTR_RINV_ZETAZETA parameter for Gaussian charge distribution (Gaussian nuclear model)get_rinv_zetaset_rinv_zeta
8PTR_RANGE_OMEGAomega parameter in range-separated coulomb operator (>0 for LR, <0 for SR)get_range_coulomb
omega
set_range_coulomb
set_omega
9PTR_F12_ZETAYukawa potential and Slater-type geminal $e^{-\zeta r}$
10PTR_GTG_ZETAGaussian type geminal $e^{-\zeta r^2}$
11NGRIDSFor hybrid integrals with grids
12PTR_GRIDSLocation of grids for int1e_grids or variants
17AS_RINV_ORIG_ATOMPosition of atom to be used as origin in $1/(r-R_O)$ for ECP derivativesget_rinv_origin_atom
set_rinv_origin_atom
18AS_ECPBAS_OFFSETOffset of ECP basis in bas field, used for ECP integralsmerge_ecpbas
decopule_ecpbas
19AS_NECPBASNumber of ECP shells in ecpbas fieldmerge_ecpbas
decopule_ecpbas
20PTR_ENV_STARTStart of data
§cint_type: CIntType

Type of integral.

  • Spheric: spherical harmonics, which is the most common case.
  • Cartesian: cartesian coordinates.
  • Spinor: spinor integrals, which are used in relativistic calculations.

Implementations§

Source§

impl CInt

Implementation of integral at higher API level (for basic user usage).

Source

pub fn integrate( &self, intor: &str, aosym: impl Into<CIntSymm>, shls_slice: impl Into<ShlsSlice>, ) -> CIntOutput<f64>

Main electronic integral driver (for non-spinor type) in column-major.

Following kinds of integrals are supported:

  • general integrals,
  • ECP integrals,
  • 2c-1e integrals with grids.
§PySCF equivalent

mol.intor(intor, aosym, shls_slice)

§Arguments
  • intor: name of the integral to be evaluated, such as "int1e_ovlp", "int2e", "ECPscalar_iprinvip", "int2e_giao_sa10sp1spsp2", etc.
  • aosym: symmetry of the integral, you can specify "s1", "s2ij", "s2kl", "s4", "s8".
  • shls_slice: shell slices for evaluating sub-tensor of the total integral. Please note that this is either be None, or a slice of type &[[usize; 2]] or something similar (vectors, arrays) with length the same to the number of centers in integral.

Does not check whether AO symmetry is correct to the corresponding integrator

For example,

  • int2e_ip2 $(\mu \nu | \kappa \nabla \lambda)$ is meaningful for "s1" and "s2ij" symmetry, not meaningful for other kinds of symmetry.
  • int2e_ip1 $(\nabla \mu \nu | \kappa \lambda)$ is meaningful for "s1" and "s2kl" symmetry, not meaningful for other kinds of symmetry.
  • int2e is meaningful for all symmetries.
  • int1e_ovlp is meaningful for "s1" and "s2ij" symmetry.

However, this wrapper will generally not panic, nor raise error, if you use an incorrect symmetry for the integral. An exception is that if you specify "s2kl", "s4", "s8" on non-4-center integrals, it will raise error.

§Outputs

Returns a CIntOutput<f64> for the integral evaluation, which contains

  • out (Vec<f64>): the output buffer for the integral evaluation.
  • shape (Vec<usize>): the shape of the output buffer.

You can use .into() to convert it to a tuple of (Vec<f64>, Vec<usize>):

let (out, shape) = cint_data.integrate("int1e_ovlp", "s2ij", None).into();
§Examples

The following example uses a pre-defined water molecule with def2-TZVP basis set.

The construction of CInt is not performed in this crate, but should be provided by user. We refer to function init_h2o_def2_tzvp for how to define a CInt instance.

§General Example
use libcint::prelude::*;
let cint_data = init_h2o_def2_tzvp();

// aosym default: "s1"
// shls_slice default: None (evaluating all shells)
let (out, shape) = cint_data.integrate("int1e_ovlp", None, None).into();
assert_eq!(shape, vec![43, 43]);

// utilize "s2ij" symmetry
let (out, shape) = cint_data.integrate("int3c2e_ip2", "s2ij", None).into();
assert_eq!(shape, vec![946, 43, 3]);

// calculate sub-tensor of the integral
let nbas = cint_data.nbas();
let shl_slices = [[0, nbas], [0, nbas], [3, 12]]; // 3-centers for int3c2e_ip2
let (out, shape) = cint_data.integrate("int3c2e_ip2", "s2ij", shl_slices).into();
assert_eq!(shape, vec![946, 29, 3]);

let shls_slice = [[0, nbas], [0, nbas], [3, 12], [4, 15]]; // 4-centers for int2e_ip2
let (out, shape) = cint_data.integrate("int2e_ip2", "s2ij", shls_slice).into();
assert_eq!(shape, vec![946, 29, 33, 3]);
§ECP

ECP (effective core potential) integrals are also supported.

use libcint::prelude::*;
let cint_data = init_sb2me4_cc_pvtz();

let (out, shape) = cint_data.integrate("ECPscalar_iprinvip", "s1", None).into();
assert_eq!(shape, vec![366, 366, 9]);
§Integral with Grids

For integrals with grids, such as int1e_grids, int1e_grids_ip, you may perform integrate with function with_grids or directly set by set_grids:

use libcint::prelude::*;
let mut cint_data = init_h2o_def2_tzvp();
let grids = vec![[0., 1., 2.], [3., 4., 5.]]; // ngrids = 2

let (out, shape) = cint_data.with_grids(&grids, |data| {
    data.integrate("int1e_grids_ip", "s1", None).into()
});
// [grids, bas_i, bas_j, components]
assert_eq!(shape, vec![2, 43, 43, 3]);
§Column-major convention

integrate always returns column-major shape with its output buffer.

Please note that integrate is somehow different to PySCF’s convention. The user should be very clear about the convention before using this function, especially when you are evaluating integrals with derivatives or using shls_slice option.

The following table summarizes difference between PySCF and CInt conventions.

  • “Strides” are indicated by numbers. Recall that a tensor is defined by its data buffer in RAM and layout; the layouot contains shape, strides and offset.

    Those numbers are not the actual stride size, but actually indicates the relative size of that axis in tensor. For row-major tensors of 3-dimensional tensor, it is $[2, 1, 0]$; for col-major tensors, it is $[0, 1, 2]$.

  • $t$ indicates the number of components in the integral.

  • $\mu, \nu, \kappa, \lambda$ indicate the indices of the atomic orbitals (basis).

  • $\mathrm{tp}(\mu \nu)$ means triangular-packed shape of the $(\mu, \nu)$ indices pair. This is always packed by upper-triangular indices for col-major, or equivalently lower-triangular indices for row-major.

  • $g$ indicates grids, which is used in integrals like int1e_grids, int1e_grids_ip.

  • “same layout” means the underlying data is the same, regardless of how shape and strides are defined. If same data layout, it means CInt data is the transposed PySCF’s data, without any additional copy or memory allocation.

centercompsymmexamplePySCF shapePySCF stridesCInt shapeCInt stridessame layout
2s1int1e_ovlp$[\mu, \nu]$$[0, 1]$$[\mu, \nu]$$[0, 1]$
2s1int1e_ipkin$[t, \mu, \nu]$$[2, 0, 1]$$[\mu, \nu, t]$$[0, 1, 2]$
2s2ijint1e_ovlpNot supported-$[\mathrm{tp}(\mu \nu)]$$[0]$-
2s2ijint1e_ovlpNot supported-$[\mathrm{tp}(\mu \nu), t]$$[0, 1]$-
2s1int1e_grids$[g, \mu, \nu]$$[0, 1, 2]$$[g, \mu, \nu]$$[0, 1, 2]$
2s1int1e_grids_ip$[t, g, \mu, \nu]$$[3, 0, 1, 2]$$[g, \mu, \nu, t]$$[0, 1, 2, 3]$
3s1int3c2e$[\mu, \nu, \kappa]$$[0, 1, 2]$$[\mu, \nu, \kappa]$$[0, 1, 2]$
3s1int3c2e_ip1$[t, \mu, \nu, \kappa]$$[3, 0, 1, 2]$$[\mu, \nu, \kappa, t]$$[0, 1, 2, 3]$
3s2ijint3c2e$[\mathrm{tp}(\mu \nu), \kappa]$$[0, 1]$$[\mathrm{tp}(\mu \nu), \kappa]$$[0, 1]$
3s2ijint3c2e_ip2$[t, \mathrm{tp}(\mu \nu), \kappa]$$[2, 0, 1]$$[\mathrm{tp}(\mu \nu), \kappa, t]$$[0, 1, 2]$
4s1int2e$[\mu, \nu, \kappa, \lambda]$$[3, 2, 1, 0]$$[\mu, \nu, \kappa, \lambda]$$[0, 1, 2, 3]$
4s1int2e_ip1$[t, \mu, \nu, \kappa, \lambda]$$[4, 3, 2, 1, 0]$$[\mu, \nu, \kappa, \lambda, t]$$[0, 1, 2, 3, 4]$
4s2ijint2e$[\mathrm{tp}(\mu \nu), \kappa, \lambda]$$[2, 1, 0]$$[\mathrm{tp}(\mu \nu), \kappa, \lambda]$$[0, 1, 2]$
4s2ijint2e_ip2$[t, \mathrm{tp}(\mu \nu), \kappa, \lambda]$$[3, 2, 1, 0]$$[\mathrm{tp}(\mu \nu), \kappa, \lambda, t]$$[0, 1, 2, 3]$
4s2klint2e$[\mu, \nu, \mathrm{tp}(\kappa \lambda)]$$[2, 1, 0]$$[\mu, \nu, \mathrm{tp}(\kappa \lambda)]$$[0, 1, 2]$
4s2klint2e_ip1$[t, \mu, \nu, \mathrm{tp}(\kappa \lambda)]$$[3, 2, 1, 0]$$[\mu, \nu, \mathrm{tp}(\kappa \lambda), t]$$[0, 1, 2, 3]$
4s4int2e$[\mathrm{tp}(\mu \nu), \mathrm{tp}(\kappa \lambda)]$$[1, 0]$$[\mathrm{tp}(\mu \nu), \mathrm{tp}(\kappa \lambda)]$$[0, 1]$
4s8int2e$[\mathrm{tp}(\mathrm{tp}(\mu \nu) \mathrm{tp}(\kappa \lambda))]$$[0]$$[\mathrm{tp}(\mathrm{tp}(\mu \nu) \mathrm{tp}(\kappa \lambda))]$$[0]$
§Spheric or Cartesian

The CInt supports both spherical and cartesian integrals. You can either set CInt::cint_type or use _sph or _cart suffix in integrator name argument intor:

use libcint::prelude::*;
let mut cint_data = init_h2o_def2_tzvp();

// spherical integral
let (out, shape) = cint_data.integrate("int1e_ovlp", None, None).into();
assert_eq!(shape, vec![43, 43]);

// cartesian integral using with-clause
let (out, shape) = cint_data.with_cint_type("cart", |cint_data| {
    cint_data.integrate("int1e_ovlp", None, None).into()
});
assert_eq!(shape, vec![48, 48]);

// cartesian integral using suffix
let (out, shape) = cint_data.integrate("int1e_ovlp_cart", None, None).into();
assert_eq!(shape, vec![48, 48]);

This function cannot handle spinor integral

Due to rust’s strict type system, it is very difficult to handle both spinor and spheric/cartesian integrals in the same function. So spinor integral should be called by integrate_spinor, which output is Complex<f64>.

let (out, shape) = cint_data.integrate("int1e_ovlp_spinor", None, None).into();
// panics: Expected float type size 16 bytes, but got 8 bytes.
§See also
Source

pub fn integrate_spinor( &self, intor: &str, aosym: impl Into<CIntSymm>, shls_slice: impl Into<ShlsSlice>, ) -> CIntOutput<Complex<f64>>

Main electronic integral driver (for spinor type) in column-major.

We refer most documentation to integrate.

§PySCF equivalent

mol.intor(f"{intor}_spinor", aosym, shls_slice)

§Examples

The following example uses a pre-defined water molecule with def2-TZVP basis set.

use libcint::prelude::*;
let mut cint_data = init_h2o_def2_tzvp();

// spinor integral using with-clause
let (out, shape) = cint_data.with_cint_type("spinor", |cint_data| {
   cint_data.integrate_spinor("int1e_ovlp", None, None).into()
});
assert_eq!(shape, vec![86, 86]);

// spinor integral using suffix
let (out, shape) = cint_data.integrate_spinor("int1e_ovlp_spinor", None, None).into();
assert_eq!(shape, vec![86, 86]);

This function cannot handle spheric or cartesian integral

Due to rust’s strict type system, it is very difficult to handle both spinor and spheric/cartesian integrals in the same function. So spheric and cartesian integral should be called by integrate, which output is f64.

let (out, shape) = cint_data.integrate_spinor("int1e_ovlp_sph", None, None).into();
// panics: Expected float type size 8 bytes, but got 16 bytes.
§See also
Source

pub fn integrate_f( &self, intor: &str, aosym: impl Into<CIntSymm>, shls_slice: impl Into<ShlsSlice>, ) -> Result<CIntOutput<f64>, CIntError>

Main electronic integral driver (for non-spinor type) in column-major.

This function is fallible.

§See also
Source

pub fn integrate_spinor_f( &self, intor: &str, aosym: impl Into<CIntSymm>, shls_slice: impl Into<ShlsSlice>, ) -> Result<CIntOutput<Complex<f64>>, CIntError>

Main electronic integral driver (for spinor type) in column-major.

This function is fallible.

§See also
Source

pub fn integrate_cross<'l>( intor: &str, mols: impl AsRef<[&'l CInt]>, aosym: impl Into<CIntSymm>, shls_slice: impl Into<ShlsSlice>, ) -> CIntOutput<f64>

Integrate with multiple molecules in column-major.

§PySCF equivalent
  • 2-center: gto.intor_cross(intor, mol1, mol2)
  • 3-center: df.incore.aux_e2(mol1, mol2, intor, aosym, shls_slice), df.incore.aux_e1(mol1, mol2, intor, aosym, shls_slice)
§Arguments
  • intor: name of the integral to be evaluated, such as "int1e_ovlp", "int2e", "ECPscalar_iprinvip", "int2e_giao_sa10sp1spsp2", etc.
  • mols: references to a list of CInt molecules; the number of molecules must be the same value to number of centers in the integral.
  • aosym: symmetry of the integral, you can specify "s1", "s2ij", "s2kl", "s4", "s8".
  • shls_slice: shell slices for evaluating sub-tensor of the total integral. Please note that this is either be None, or a slice of type &[[usize; 2]] or something similar (vectors, arrays) with length the same to the number of components in integral. Also, the slices corresponds to molecules in mols argument accordingly.
§Examples
use libcint::prelude::*;
let data_tzvp = init_h2o_def2_tzvp();
let data_jk = init_h2o_def2_jk();

// pyscf equilvant
//     out = gto.intor_cross("int1e_ovlp", mol_tzvp, mol_jk)
//     lib.fp(out.T), out.shape
let (out, shape) = CInt::integrate_cross("int1e_ovlp", [&data_tzvp, &data_jk], None, None).into();
assert_eq!(shape, vec![43, 113]);
assert!((cint_fp(&out) - 11.25500947854174).abs() < 1e-10);

// pyscf equilvant
//     out = df.incore.aux_e2(mol_tzvp, mol_jk, "int3c2e_ip2", "s2ij")
//     out_c = out.transpose(0, 2, 1)
//     lib.fp(out_c), out_c.shape[::-1]
let (out, shape) = CInt::integrate_cross("int3c2e_ip2", [&data_tzvp, &data_tzvp, &data_jk], "s2ij", None).into();
assert_eq!(shape, vec![946, 113, 3]);
assert!((cint_fp(&out) - 10.435234769997802).abs() < 1e-10);
§See also
Source

pub fn integrate_cross_f<'l>( intor: &str, mols: impl AsRef<[&'l CInt]>, aosym: impl Into<CIntSymm>, shls_slice: impl Into<ShlsSlice>, ) -> Result<CIntOutput<f64>, CIntError>

Integrate with multiple molecules in column-major.

This function is fallible.

§See also
Source

pub fn integrate_cross_spinor<'l>( intor: &str, mols: impl AsRef<[&'l CInt]>, aosym: impl Into<CIntSymm>, shls_slice: impl Into<ShlsSlice>, ) -> CIntOutput<Complex<f64>>

Integrate with multiple molecules (for spinor type) in column-major.

§See also
Source

pub fn integrate_cross_spinor_f<'l>( intor: &str, mols: impl AsRef<[&'l CInt]>, aosym: impl Into<CIntSymm>, shls_slice: impl Into<ShlsSlice>, ) -> Result<CIntOutput<Complex<f64>>, CIntError>

Integrate with multiple molecules (for spinor type) in column-major.

This function is fallible.

§See also
Source

pub fn integrate_row_major( &self, intor: &str, aosym: impl Into<CIntSymm>, shls_slice: impl Into<ShlsSlice>, ) -> CIntOutput<f64>

Main electronic integral driver (for non-spinor type) in row-major.

Following kinds of integrals are supported:

  • general integrals,
  • ECP integrals,
  • 2c-1e integrals with grids.

We refer most documentation to integrate. Those two functions share the same arguments, but the output buffer is in row-major shape; the shape of integrate and integrate_row_major are also different. Follow the rest documentation of this function for more information.

§Examples

The following example uses a pre-defined water molecule with def2-TZVP basis set.

use libcint::prelude::*;
let cint_data = init_h2o_def2_tzvp();

// aosym default: "s1"
// shls_slice default: None (evaluating all shells)
let (out, shape) = cint_data.integrate_row_major("int1e_ovlp", None, None).into();
assert_eq!(shape, vec![43, 43]);

// utilize "s2ij" symmetry
let (out, shape) = cint_data.integrate_row_major("int3c2e_ip2", "s2ij", None).into();
assert_eq!(shape, vec![3, 946, 43]);

// calculate sub-tensor of the integral
let nbas = cint_data.nbas();
let shl_slices = [[0, nbas], [0, nbas], [3, 12]]; // 3-centers for int3c2e_ip2
let (out, shape) = cint_data.integrate_row_major("int3c2e_ip2", "s2ij", shl_slices).into();
assert_eq!(shape, vec![3, 946, 29]);

let shls_slice = [[0, nbas], [0, nbas], [3, 12], [4, 15]]; // 4-centers for int2e_ip2
let (out, shape) = cint_data.integrate_row_major("int2e_ip2", "s2ij", shls_slice).into();
assert_eq!(shape, vec![3, 946, 29, 33]);
§Row-major convention

integrate_row_major always returns column-major shape with its output buffer.

Though shape of this function is the same to PySCF’s convention, please note that integrate_row_major does not share the same memory layout to PySCF’s 2/3-center integrals. The user should use these integrals with caution, especially when you are concerned for efficiency, or performing triangular matrices unpack. Same algorithms in PySCF when performing density fitting may not show the same efficiency using this function.

Also, component of integrals in function integrate_row_major are presented in the first axis (the most non-contiguous memory layout for row-major). Compared to function, integrate, where components are presented in the last axis (the most non-contiguous memory layout for column-major).

centercompsymmexampleshapePySCF stridesCInt stridessame layout
2s1int1e_ovlp$[\mu, \nu]$$[0, 1]$$[1, 0]$
2s1int1e_ipkin$[t, \mu, \nu]$$[2, 0, 1]$$[2, 1, 0]$
2s2ijint1e_ovlpNot supported-$[0]$-
2s2ijint1e_ovlpNot supported-$[1, 0]$-
2s1int1e_grids$[g, \mu, \nu]$$[0, 1, 2]$$[2, 1, 0]$
2s1int1e_grids_ip$[t, g, \mu, \nu]$$[3, 0, 1, 2]$$[3, 2, 1, 0]$
3s1int3c2e$[\mu, \nu, \kappa]$$[0, 1, 2]$$[2, 1, 0]$
3s1int3c2e_ip1$[t, \mu, \nu, \kappa]$$[3, 0, 1, 2]$$[3, 2, 1, 0]$
3s2ijint3c2e$[\mathrm{tp}(\mu \nu), \kappa]$$[0, 1]$$[1, 0]$
3s2ijint3c2e_ip2$[t, \mathrm{tp}(\mu \nu), \kappa]$$[2, 0, 1]$$[2, 1, 0]$
4s1int2e$[\mu, \nu, \kappa, \lambda]$$[3, 2, 1, 0]$$[3, 2, 1, 0]$
4s1int2e_ip1$[t, \mu, \nu, \kappa, \lambda]$$[4, 3, 2, 1, 0]$$[4, 3, 2, 1, 0]$
4s2ijint2e$[\mathrm{tp}(\mu \nu), \kappa, \lambda]$$[2, 1, 0]$$[2, 1, 0]$
4s2ijint2e_ip2$[t, \mathrm{tp}(\mu \nu), \kappa, \lambda]$$[3, 2, 1, 0]$$[3, 2, 1, 0]$
4s2klint2e$[\mu, \nu, \mathrm{tp}(\kappa \lambda)]$$[2, 1, 0]$$[2, 1, 0]$
4s2klint2e_ip1$[t, \mu, \nu, \mathrm{tp}(\kappa \lambda)]$$[3, 2, 1, 0]$$[3, 2, 1, 0]$
4s4int2e$[\mathrm{tp}(\mu \nu), \mathrm{tp}(\kappa \lambda)]$$[1, 0]$$[1, 0]$
4s8int2e$[\mathrm{tp}(\mathrm{tp}(\mu \nu) \mathrm{tp}(\kappa \lambda))]$$[0]$$[0]$
§See also
Source

pub fn integrate_row_major_f( &self, intor: &str, aosym: impl Into<CIntSymm>, shls_slice: impl Into<ShlsSlice>, ) -> Result<CIntOutput<f64>, CIntError>

Main electronic integral driver (for non-spinor type) in row-major.

This function is fallible.

§See also
Source

pub fn integrate_row_major_spinor( &self, intor: &str, aosym: impl Into<CIntSymm>, shls_slice: impl Into<ShlsSlice>, ) -> CIntOutput<Complex<f64>>

Main electronic integral driver (for spinor type) in row-major.

We refer most documentation to integrate_spinor and integrate_row_major for more information.

§Examples

The following example uses a pre-defined water molecule with def2-TZVP basis set.

use libcint::prelude::*;
let cint_data = init_h2o_def2_tzvp();

let (out, shape) = cint_data.integrate_row_major_spinor("int1e_ipovlp_spinor", None, None).into();
assert_eq!(shape, vec![3, 86, 86]);
§See also
Source

pub fn integrate_row_major_spinor_f( &self, intor: &str, aosym: impl Into<CIntSymm>, shls_slice: impl Into<ShlsSlice>, ) -> Result<CIntOutput<Complex<f64>>, CIntError>

Main electronic integral driver (for spinor type) in row-major.

This function is fallible.

§See also
Source

pub fn integrate_cross_row_major<'l>( intor: &str, mols: impl AsRef<[&'l CInt]>, aosym: impl Into<CIntSymm>, shls_slice: impl Into<ShlsSlice>, ) -> CIntOutput<f64>

Integrate with multiple molecules in row-major.

We refer most documentation to integrate_cross, and also notice the row-major convention that described in integrate_row_major.

§Examples
use libcint::prelude::*;
let data_tzvp = init_h2o_def2_tzvp();
let data_jk = init_h2o_def2_jk();

// pyscf equilvant
//     out = gto.intor_cross("int1e_ovlp", mol_tzvp, mol_jk)
//     lib.fp(out), out.shape
let (out, shape) = CInt::integrate_cross_row_major("int1e_ovlp", [&data_tzvp, &data_jk], None, None).into();
assert_eq!(shape, vec![43, 113]);
assert!((cint_fp(&out) - 7.422726471473346).abs() < 1e-10);

// pyscf equilvant
//     out = df.incore.aux_e2(mol_tzvp, mol_jk, "int3c2e_ip2", "s2ij")
//     lib.fp(out), out.shape
let (out, shape) = CInt::integrate_cross_row_major("int3c2e_ip2", [&data_tzvp, &data_tzvp, &data_jk], "s2ij", None).into();
assert_eq!(shape, vec![3, 946, 113]);
assert!((cint_fp(&out) - 15.423815120360992).abs() < 1e-10);
§See also
Source

pub fn integrate_cross_row_major_f<'l>( intor: &str, mols: impl AsRef<[&'l CInt]>, aosym: impl Into<CIntSymm>, shls_slice: impl Into<ShlsSlice>, ) -> Result<CIntOutput<f64>, CIntError>

Integrate with multiple molecules in row-major.

This function is fallible.

§See also
Source

pub fn integrate_cross_row_major_spinor<'l>( intor: &str, mols: impl AsRef<[&'l CInt]>, aosym: impl Into<CIntSymm>, shls_slice: impl Into<ShlsSlice>, ) -> CIntOutput<Complex<f64>>

Integrate with multiple molecules (for spinor type) in row-major.

§See also
Source

pub fn integrate_cross_row_major_spinor_f<'l>( intor: &str, mols: impl AsRef<[&'l CInt]>, aosym: impl Into<CIntSymm>, shls_slice: impl Into<ShlsSlice>, ) -> Result<CIntOutput<Complex<f64>>, CIntError>

Integrate with multiple molecules (for spinor type) in row-major.

This function is fallible.

§See also
Source§

impl CInt

Serde conversion between CInt and other serializable formats (JSON currently).

Source

pub fn to_json(&self) -> String

Convert CInt to JSON string.

Source

pub fn from_json(token: &str) -> CInt

Convert JSON string (or the path of JSON file) to CInt.

This function accepts the JSON string from PySCF’s mol.dumps().

Source

pub fn to_json_f(&self) -> Result<String, CIntError>

Source

pub fn from_json_f(token: &str) -> Result<CInt, CIntError>

Source§

impl CInt

Implementation of legacy initializers for CInt.

Source

pub fn new() -> Self

Create a new empty CInt instance (not recommended).

In most cases, you are encouraged to directly construct the CInt instance.

If you are considering transforming PySCF’s mol to CInt, you can use CInt::from_json to parse the JSON string from PySCF’s mol. dumps().

Source

pub fn initial_r2c( &mut self, atm: &Vec<Vec<i32>>, natm: i32, bas: &Vec<Vec<i32>>, nbas: i32, env: &Vec<f64>, )

Legacy initializer for CInt (without ECP).

Source

pub fn initial_r2c_with_ecp( &mut self, atm: &Vec<Vec<i32>>, natm: i32, bas: &Vec<Vec<i32>>, nbas: i32, ecp: &Vec<Vec<i32>>, necp: i32, env: &Vec<f64>, )

Legacy initializer for CInt (with ECP).

Source§

impl CInt

Properties of the CInt instance (compute and memory cost is not essential in this module).

Source

pub fn has_ecp(&self) -> bool

Whether pseudo potential is used in the system.

§PySCF Equivalent

Method Mole.has_ecp

§Examples
use libcint::prelude::*;
let cint_data = init_h2o_def2_tzvp();
assert!(!cint_data.has_ecp());

let cint_data = init_sb2me4_cc_pvtz();
assert!(cint_data.has_ecp());
Source

pub fn has_ecp_soc(&self) -> bool

Whether spin-orbit coupling is enabled in ECP.

§PySCF Equivalent

Method Mole.has_ecp_soc

§Examples
use libcint::prelude::*;
let cint_data = init_sb2me4_cc_pvtz();
assert!(!cint_data.has_ecp_soc());
Source

pub fn nbas(&self) -> usize

Number of shells in the system.

This does not count ECP shells.

Please note that, self.bas.len() may not be the actual number of shells, because in some cases, ECP shells are merged into the GTO shells.

§PySCF Equivalent

Attribute Mole.nbas

§Examples
use libcint::prelude::*;

let cint_data = init_h2o_def2_tzvp();
assert_eq!(cint_data.nbas(), 19);

let cint_data = init_sb2me4_cc_pvtz();
assert_eq!(cint_data.nbas(), 130);
Source

pub fn natm(&self) -> usize

Number of atoms in the system.

Source

pub fn bas_ptr(&self) -> *const c_int

Pointer to the shell data.

Source

pub fn atm_ptr(&self) -> *const c_int

Pointer to the atom data.

Source

pub fn env_ptr(&self) -> *const f64

Pointer to the environment data.

Source

pub fn atom_charge(&self, atm_id: usize) -> f64

Nuclear effective charge of the given atom id.

§Note

atom_charge != charge(atom_symbol) when ECP is enabled.

Number of electrons screened by ECP can be obtained by charge(atom_symbol) - atom_charge.

§PySCF Equivalent

Method Mole.atom_charge

§Examples
use libcint::prelude::*;
let cint_data = init_h2o_def2_tzvp();
assert_eq!(cint_data.atom_charge(0), 8.0);  // O  (8)
assert_eq!(cint_data.atom_charge(1), 1.0);  // H  (1)

let cint_data = init_sb2me4_cc_pvtz();
assert_eq!(cint_data.atom_charge(0), 23.0); // Sb (51) with ECP (-36)
assert_eq!(cint_data.atom_charge(2), 6.0);  // C  (6)
Source

pub fn atom_charges(&self) -> Vec<f64>

List of Nuclear effective charge of all atoms in system.

§Note

atom_charge != charge(atom_symbol) when ECP is enabled.

Number of electrons screened by ECP can be obtained by charge(atom_symbol) - atom_charge.

§PySCF Equivalent

Method Mole.atom_charges

§Examples
use libcint::prelude::*;
let cint_data = init_h2o_def2_tzvp();
assert_eq!(cint_data.atom_charges(), vec![8., 1., 1.]);

// For Sb2Me4, the first atom is Sb (51) with ECP (-36), so the charge is 23.
let cint_data = init_sb2me4_cc_pvtz();
assert_eq!(cint_data.atom_charges(), vec![23., 23., 6., 6., 6., 6., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]);
Source

pub fn len_spinor(l: i32, kappa: i32) -> usize

The number of spinor associated with given angular momentum $l$ and kappa $\kappa$.

  • If $\kappa = 0$, it returns $4 l + 2$.
  • If $\kappa > 0$, it returns $2 l + 2$.
  • If $\kappa < 0$, it returns $2 l$.
§PySCF Equivalent

Function gto.mole.len_spinor

Source

pub fn len_cart(l: i32) -> usize

The number of Cartesian function associated with given angular momentum $l$.

This will gives $\frac{(l + 1) (l + 2)}{2}$

§PySCF Equivalent

Function gto.mole.len_cart

Source

pub fn len_sph(l: i32) -> usize

The number of spherical function associated with given angular momentum $l$.

This will gives $2 l + 1$.

§PySCF Equivalent

Function gto.mole.len_sph

Source

pub fn make_loc(&self) -> Vec<usize>

Location mapping from shell to basis.

The type of integral is specified by struct field cint_type.

Output vector is of length nshl + 1, where nshl is the number of shells.

§PySCF Equivalent

This implementation follows gto.moleintor.make_loc.

For gto.Mole object, methods ao_loc, ao_loc_nr, ao_loc_2c are also relevant.

§Examples
use libcint::prelude::*;
let cint_data = init_h2o_def2_tzvp();

let loc_sph = cint_data.make_loc();
assert_eq!(loc_sph, vec![ 0,  1,  2,  3,  4,  5,  8, 11, 14, 19, 24, 31, 32, 33, 34, 37, 38, 39, 40, 43]);
Source

pub fn ao_loc(&self) -> Vec<usize>

Location mapping from shell to basis.

§See also

CInt::make_loc

Source

pub fn make_loc_with_type(&self, cint_type: CIntType) -> Vec<usize>

Location mapping from shell to basis (with integral type specified).

This mapping is cumulated, and can be different for sph, cart and spinor types.

Output vector is of length nshl + 1, where nshl is the number of shells.

§PySCF Equivalent

This implementation follows gto.moleintor.make_loc.

For gto.Mole object, methods ao_loc, ao_loc_nr, ao_loc_2c are also relevant.

§Examples
use libcint::prelude::*;
let cint_data = init_h2o_def2_tzvp();

let loc_sph = cint_data.make_loc_with_type(CIntType::Spheric);
assert_eq!(loc_sph, vec![ 0,  1,  2,  3,  4,  5,  8, 11, 14, 19, 24, 31, 32, 33, 34, 37, 38, 39, 40, 43]);

let loc_cart = cint_data.make_loc_with_type(CIntType::Cartesian);
assert_eq!(loc_cart, vec![ 0,  1,  2,  3,  4,  5,  8, 11, 14, 20, 26, 36, 37, 38, 39, 42, 43, 44, 45, 48]);

let loc_spinor = cint_data.make_loc_with_type(CIntType::Spinor);
assert_eq!(loc_spinor, vec![ 0,  2,  4,  6,  8, 10, 16, 22, 28, 38, 48, 62, 64, 66, 68, 74, 76, 78, 80, 86]);
Source

pub fn nao(&self) -> usize

Get the number of basis (atomic orbitals).

The type of integral is specified by struct field cint_type.

This value is the same to the last of CInt::make_loc_with_type.

§PySCF Equivalent

For gto.Mole object, methods nao_nr, nao_cart, nao_2c are relevant.

§Examples
use libcint::prelude::*;
let cint_data = init_h2o_def2_tzvp();

let nao_sph = cint_data.nao();
assert_eq!(nao_sph, 43);

let cint_data = init_sb2me4_cc_pvtz();
let nao_sph = cint_data.nao();
assert_eq!(nao_sph, 366);
Source

pub fn nao_with_type(&self, cint_type: CIntType) -> usize

Get the number of basis (atomic orbitals, with integral type specified).

This value is different for sph, cart and spinor types.

This value is the same to the last of CInt::make_loc_with_type.

§PySCF Equivalent

For gto.Mole object, methods nao_nr, nao_cart, nao_2c are relevant.

§Examples
use libcint::prelude::*;
let cint_data = init_h2o_def2_tzvp();

let nao_sph = cint_data.nao_with_type(CIntType::Spheric);
assert_eq!(nao_sph, 43);

let nao_cart = cint_data.nao_with_type(CIntType::Cartesian);
assert_eq!(nao_cart, 48);

let nao_spinor = cint_data.nao_with_type(CIntType::Spinor);
assert_eq!(nao_spinor, 86);

let cint_data = init_sb2me4_cc_pvtz();
let nao_sph = cint_data.nao_with_type(CIntType::Spheric);
assert_eq!(nao_sph, 366);
Source

pub fn atom_coord(&self, atm_id: usize) -> [f64; 3]

Coordinates of the given atom id in unit Bohr (a.u.).

§PySCF Equivalent

Method Mole.atom_coord with unit="Bohr".

Source

pub fn atom_coords(&self) -> Vec<[f64; 3]>

Coordinates of all atoms in unit Bohr (a.u.).

§PySCF Equivalent

Method Mole.atom_coords with unit="Bohr".

§Examples
use libcint::prelude::*;
let cint_data = init_h2o_def2_tzvp();
let coords = cint_data.atom_coords();
// Output:
// [[  0.000000,   0.000000,   0.000000],
//  [  1.776343,   0.000000,   0.000000],
//  [ -0.444761,   0.000000,   1.719762]]
assert_relative_eq!(cint_fingerprint(&coords), -2.4358371781626658, max_relative=1e-12);
Source

pub fn atom_nshells(&self, atm_id: usize) -> usize

Number of shells of the given atom

§PySCF Equivalent

Method Mole.atom_nshells

§Examples
use libcint::prelude::*;
let cint_data = init_h2o_def2_tzvp();
assert_eq!(cint_data.atom_nshells(0), 11);
Source

pub fn atom_shell_ids(&self, atm_id: usize) -> Vec<usize>

List of shell ids of the given atom.

§PySCF Equivalent

Method Mole.atom_shell_ids

§Examples
use libcint::prelude::*;
let cint_data = init_h2o_def2_tzvp();
assert_eq!(cint_data.atom_shell_ids(0), vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
Source

fn check_bas_id(&self, bas_id: usize)

Source

pub fn bas_coord(&self, bas_id: usize) -> [f64; 3]

Coordinates of the given shell in unit Bohr (a.u.).

§PySCF Equivalent

Method Mole.bas_coord

Source

pub fn bas_atom(&self, bas_id: usize) -> usize

The atom (0-based id) that the given shell sits on.

§PySCF Equivalent

Method Mole.bas_atom

Source

pub fn bas_angular(&self, bas_id: usize) -> usize

The angular momentum associated with the given shell.

§PySCF Equivalent

Method Mole.bas_angular

Source

pub fn bas_nctr(&self, bas_id: usize) -> usize

The number of contracted GTOs for the given shell.

§PySCF Equivalent

Method Mole.bas_nctr

Source

pub fn bas_nprim(&self, bas_id: usize) -> usize

The number of primitive GTOs for the given shell.

§PySCF Equivalent

Method Mole.bas_nprim

Source

pub fn bas_kappa(&self, bas_id: usize) -> c_int

Kappa (if l < j, -l-1, else l) of the given shell.

§PySCF Equivalent

Method Mole.bas_kappa

Source

pub fn bas_exp(&self, bas_id: usize) -> &[f64]

Exponents of the given shell.

§PySCF Equivalent

Method Mole.bas_exp

Source

pub fn bas_exps(&self) -> Vec<Vec<f64>>

Exponents of all shells.

§PySCF Equivalent

Method Mole.bas_exps

Source

pub fn aoslice_by_atom(&self) -> Vec<[usize; 4]>

Shell and basis (atomic orbitals) offsets for each atom.

This will give a list of [shl_start, shl_end, ao_start, ao_end] for each atom.

§PySCF Equivalent

Method Mole.aoslice_by_atom. This implementation does not allow arbitrary ao_loc (which can be obtained by CInt::make_loc). However, user can provide cint_type to specify if you wish to use sph, cart or spinor.

§Examples
use libcint::prelude::*;
let cint_data = init_h2o_def2_tzvp();
let aoslice = cint_data.aoslice_by_atom();
assert_eq!(aoslice, vec![
    [ 0, 11,  0, 31],
    [11, 15, 31, 37],
    [15, 19, 37, 43],
]);
Source

pub fn aoslice_by_atom_with_type(&self, cint_type: CIntType) -> Vec<[usize; 4]>

Shell and basis (atomic orbitals) offsets for each atom (with integral type specified).

This will give a list of [shl_start, shl_end, ao_start, ao_end] for each atom.

§PySCF Equivalent

Method Mole.aoslice_by_atom. This implementation does not allow arbitrary ao_loc (which can be obtained by CInt::make_loc). However, user can provide cint_type to specify if you wish to use sph, cart or spinor.

§Examples
use libcint::prelude::*;
let cint_data = init_h2o_def2_tzvp();
let aoslice = cint_data.aoslice_by_atom_with_type(CIntType::Spheric);
assert_eq!(aoslice, vec![
    [ 0, 11,  0, 31],
    [11, 15, 31, 37],
    [15, 19, 37, 43],
]);
Source

pub fn ngrids(&self) -> usize

Number of grids that is used in int1e_grids.

Note that this function is mostly for internal usage. User should generally not call this function.

Source

pub fn balance_partition(&self, block_size: usize) -> Vec<[usize; 3]>

Balances the partition of shells into blocks of a given size.

This function can be useful if the full bulk of integrals is not available in memory, and you have to generate them batch by batch.

The outputs are

  • shl_start: the starting index of the shell in the partition (included)
  • shl_end: the ending index of the shell in the partition (not included)
  • nbatch_ao: the number of AOs in the batch.
§PySCF equivalent

ao2mo.outcore.balance_partition

§Example
use libcint::prelude::*;
let cint_data = init_h2o_def2_tzvp();
let partition = cint_data.balance_partition(20);
assert_eq!(partition, vec![[0, 9, 19], [9, 17, 20], [17, 19, 4]]);
Source

pub fn balance_partition_advanced( &self, block_size: usize, start_id: Option<usize>, end_id: Option<usize>, ) -> Vec<[usize; 3]>

Balances the partition of shells into blocks of a given size.

This function is similar to CInt::balance_partition, but allows user to specify the start and end id of the shells.

Source§

impl CInt

Source

pub fn fakemol_for_charges<T>(coords: &[[f64; 3]], arg: T) -> CInt

Create a fake molecule for gaussian distributed charges.

You may also fake point charges by setting an extremely large exponent.

§PySCF equivalent

gto.fakemol_for_charges(coords, arg)

§Argument overloads

This function passes coordinates in Bohr (a.u.) unit, with &[[f64; 3]] type.

For the second argument,

  • None: use a large exponent (1e+16) to mimic point-charge.
  • f64: use a single exponent for all coordinates.
  • &[f64]: use a list of exponents, one for each coordinate.
  • (&[f64], &[f64]): use a list of exponents and contraction coefficients, one for each coordinate.
§Examples

All examples are initialized with by

use libcint::prelude::*;
let data_tzvp = init_h2o_def2_tzvp();
let coords_chg = [[0., 1., 2.], [2., 0., 1.], [0., 2., 1.]];
§Mimic point-charge by large exponent

This crate implementation:

let data_chg = CInt::fakemol_for_charges(&coords_chg, None);
let (out, shape) = CInt::integrate_cross_row_major(
    "int1e_ovlp", [&data_tzvp, &data_chg], None, None).into();
assert_eq!(shape, [43, 3]);
assert!((cint_fp(&out) - -0.12650556883004238).abs() < 1e-10);

PySCF equivalent:

coords_chg = np.asarray([[0, 1, 2], [2, 0, 1], [0, 2, 1]])
mol_chg = gto.fakemol_for_charges(coords_chg)
out = gto.intor_cross("int1e_ovlp", mol_tzvp, mol_chg)
lib.fp(out), out.shape
§Universal exponent for all coordinates
let exp_chg = 1.0;
let data_chg = CInt::fakemol_for_charges(&coords_chg, exp_chg);
let (out, shape) = CInt::integrate_cross_row_major(
    "int1e_ovlp", [&data_tzvp, &data_chg], None, None).into();
assert_eq!(shape, [43, 3]);
assert!((cint_fp(&out) - 0.0707265752256318).abs() < 1e-10);

PySCF equivalent:

exp_chg = 1.0
mol_chg = gto.fakemol_for_charges(coords_chg, exp_chg)
out = gto.intor_cross("int1e_ovlp", mol_tzvp, mol_chg)
lib.fp(out), out.shape
§Exponents for each coordinate

This crate implementation:

let exp_chg = [1.0, 2.5, 4.9];
let data_chg = CInt::fakemol_for_charges(&coords_chg, exp_chg.as_slice());
let (out, shape) = CInt::integrate_cross_row_major(
    "int1e_ovlp", [&data_tzvp, &data_chg], None, None).into();
assert_eq!(shape, [43, 3]);
assert!((cint_fp(&out) - 0.0424629237780389).abs() < 1e-10);

PySCF equivalent:

exp_chg = [1.0, 2.5, 4.9]
mol_chg = gto.fakemol_for_charges(coords_chg, exp_chg)
out = gto.intor_cross("int1e_ovlp", mol_tzvp, mol_chg)
lib.fp(out), out.shape
Source

pub fn fakemol_for_cgtf_charge( coord: [f64; 3], exponents: &[f64], coeffs: &[f64], ) -> CInt

Create a fake molecule for contracted GTO-type charge.

§PySCF equivalent

gto.fakemol_for_cgtf_charge(coord, exponents, coeffs)

§Examples

This crate implementation:

use libcint::prelude::*;
let data_tzvp = init_h2o_def2_tzvp();

let coord = [0., 1., 2.];
let exp_chg = [1.0, 2.5, 4.9];
let coef_chg = [2.8, 3.3, 0.7];
let data_chg = CInt::fakemol_for_cgtf_charge(coord, &exp_chg, &coef_chg);
let (out, shape) = CInt::integrate_cross_row_major(
    "int1e_ovlp", [&data_tzvp, &data_chg], None, None).into();
assert_eq!(shape, [43, 1]);
assert!((cint_fp(&out) - -0.054460537334674264).abs() < 1e-10);

PySCF equivalent:

mol_tzvp = gto.Mole(atom="O; H 1 0.94; H 1 0.94 2 104.5", basis="def2-TZVP").build()
coord = np.asarray([[0., 1., 2.]])
exp_chg = [1.0, 2.5, 4.9]
coef_chg = [2.8, 3.3, 0.7]
mol_chg = gto.fakemol_for_cgtf_charge(coord, exp_chg, coef_chg)
out = gto.intor_cross("int1e_ovlp", mol_tzvp, mol_chg)
lib.fp(out), out.shape
Source§

impl CInt

Usual cases for mutating CInt instance temporarily (something similar to with-clause in Python).

Source

pub fn set_cint_type(&mut self, cint_type: impl Into<CIntType>) -> &mut Self

Setter of default integral type.

§See also
Source

pub fn with_cint_type<R>( &mut self, cint_type: impl Into<CIntType>, func: impl FnOnce(&mut Self) -> R, ) -> R

With-clause of default integral type.

This will change the type of integrals computed by default:

use libcint::prelude::*;

// this test mol is Spheric
let mut cint_data = init_h2o_def2_tzvp();
let (_, shape) = cint_data.integrate("int1e_ovlp", None, None).into();
assert_eq!(cint_data.nao(), 43);
assert_eq!(shape, [43, 43]);

// change to Cartesian type
cint_data.with_cint_type("cart", |data| {
    let (_, shape) = data.integrate("int1e_ovlp", None, None).into();
    assert_eq!(data.nao(), 48);
    assert_eq!(shape, [48, 48]);
});

// change to spinor type
cint_data.with_cint_type("spinor", |data| {
    let (_, shape) = data.integrate_spinor("int1e_ovlp", None, None).into();
    assert_eq!(data.nao(), 86);
    assert_eq!(shape, [86, 86]);
});
§See also
Source

pub fn get_common_origin(&self) -> [f64; 3]

Getter of common origin for integrals (in unit Bohr).

§See also
Source

pub fn set_common_origin(&mut self, origin: [f64; 3]) -> &mut Self

Set the common origin for integrals (in unit Bohr).

§See also
Source

pub fn with_common_origin<R>( &mut self, origin: [f64; 3], func: impl FnOnce(&mut Self) -> R, ) -> R

Temporarily set the common origin for integrals (in unit Bohr).

§Example
use libcint::prelude::*;
let mut cint_data = init_h2o_def2_tzvp();

let (out, _) = cint_data.integrate_row_major("int1e_r", None, None).into();
assert!((cint_fp(&out) - -0.7587292491644675).abs() < 1e-10);

// set common origin to [0.0, 1.0, 2.0]
cint_data.with_common_origin([0.0, 1.0, 2.0], |data| {
    let (out, _) = data.integrate_row_major("int1e_r", None, None).into();
    assert!((cint_fp(&out) - 71.88577867872883).abs() < 1e-10);
});

PySCF equivalent:

mol = gto.Mole(atom="O; H 1 0.94; H 1 0.94 2 104.5", basis="def2-TZVP").build()
assert abs(lib.fp(mol.intor("int1e_r")) - -0.7587292491644675) < 1e-10
with mol.with_common_orig([0, 1, 2]):
    assert abs(lib.fp(mol.intor("int1e_r")) - 71.88577867872883) < 1e-10
§See also
Source

pub fn get_rinv_origin(&self) -> [f64; 3]

Getter of origin in evaluating $1/r$ for integrals (in unit Bohr).

§See also
Source

pub fn set_rinv_origin(&mut self, origin: [f64; 3]) -> &mut Self

Set the origin in evaluating $1/r$ for integrals (in unit Bohr).

§See also
Source

pub fn with_rinv_origin<R>( &mut self, origin: [f64; 3], func: impl FnOnce(&mut Self) -> R, ) -> R

Temporarily set the origin in evaluating $1/r$ for integrals (in unit Bohr).

§Example
use libcint::prelude::*;
let mut cint_data = init_h2o_def2_tzvp();

let (out, _) = cint_data.integrate_row_major("int1e_rinv", None, None).into();
assert!((cint_fp(&out) - 51.806443495904794).abs() < 1e-10);

// set rinv origin to [0.0, 1.0, 2.0]
cint_data.with_rinv_origin([0.0, 1.0, 2.0], |data| {
    let (out, _) = data.integrate_row_major("int1e_rinv", None, None).into();
    assert!((cint_fp(&out) - 15.72929399764994).abs() < 1e-10);
});

PySCF equivalent:

mol = gto.Mole(atom="O; H 1 0.94; H 1 0.94 2 104.5", basis="def2-TZVP").build()
assert abs(lib.fp(mol.intor("int1e_rinv")) - 51.806443495904794) < 1e-10
with mol.with_rinv_orig([0, 1, 2]):
    assert abs(lib.fp(mol.intor("int1e_rinv")) - 15.72929399764994) < 1e-10
§See also
Source

pub fn get_rinv_origin_atom(&self) -> usize

Getter of the origin atom in evaluating $1/r$ for ECP integrals.

§See also
Source

pub fn set_rinv_origin_atom(&mut self, atm_id: usize) -> &mut Self

Setter of the origin atom in evaluating $1/r$ for ECP integrals.

§See also
Source

pub fn with_rinv_origin_atom<R>( &mut self, atm_id: usize, func: impl FnOnce(&mut Self) -> R, ) -> R

Temporarily set the origin atom in evaluating $1/r$ for ECP integrals.

This option alone is not useful. See with_rinv_at_nucleus for more information.

§See also
Source

pub fn get_range_coulomb(&self) -> f64

Getter of the range separation parameter $\omega$ for Coulomb integrals.

§See also
§Alias
Source

pub fn set_range_coulomb(&mut self, range: f64) -> &mut Self

Setter the range separation parameter $\omega$ for Coulomb integrals.

§See also
§Alias
Source

pub fn with_range_coulomb<R>( &mut self, range: f64, func: impl FnOnce(&mut Self) -> R, ) -> R

Temporarily set the range separation parameter $\omega$ for Coulomb integrals.

Common operator of ERI (for example, int2e) is $1 / r$; however, in range separation scheme, the long-range operator is $\mathrm{erf} (\omega r) / r$, and the short-range operator is $\mathrm{erfc} (\omega r) / r$.

For libcint convention,

  • Positive omega indicates long-range Coulomb operator.
  • Negative omega indicates short-range Coulomb operator.
  • Exactly zero omega indicates the original Coulomb operator $1/r$.
§Example
use libcint::prelude::*;
let mut cint_data = init_h2o_def2_tzvp();

let (out, _) = cint_data.integrate_row_major("int2e", None, None).into();
assert!((cint_fp(&out) - 70.00106603114841).abs() < 1e-10);

// set range separation parameter to 0.5 (long-range)
cint_data.with_range_coulomb(0.5, |data| {
   let (out, _) = data.integrate_row_major("int2e", None, None).into();
   assert!((cint_fp(&out) - 23.8282413132626).abs() < 1e-10);
});

// set range separation parameter to -0.5 (short-range)
cint_data.with_range_coulomb(-0.5, |data| {
    let (out, _) = data.integrate_row_major("int2e", None, None).into();
    assert!((cint_fp(&out) - 46.17282471793578).abs() < 1e-10);
});

PySCF equivalent:

mol = gto.Mole(atom="O; H 1 0.94; H 1 0.94 2 104.5", basis="def2-TZVP").build()
assert abs(lib.fp(mol.intor("int2e")) - 70.00106603114841) < 1e-10
with mol.with_range_coulomb(0.5):
    assert abs(lib.fp(mol.intor("int2e")) - 23.8282413132626) < 1e-10
with mol.with_range_coulomb(-0.5):
    assert abs(lib.fp(mol.intor("int2e")) - 46.17282471793578) < 1e-10
§See also
§Alias
Source

pub fn omega(&self) -> f64

Getter of the range separation parameter $\omega$ for Coulomb integrals.

§Alias
Source

pub fn set_omega(&mut self, omega: f64) -> &mut Self

Setter of the range separation parameter $\omega$ for Coulomb integrals.

§Alias
Source

pub fn with_omega<R>( &mut self, omega: f64, func: impl FnOnce(&mut Self) -> R, ) -> R

Temporarily set the range separation parameter $\omega$ for Coulomb integrals.

§Alias
Source

pub fn with_long_range_coulomb<R>( &mut self, omega: f64, func: impl FnOnce(&mut Self) -> R, ) -> R

Temporarily set the range separation parameter $\omega$ for Coulomb integrals (long range).

This function only accepts positive omega values.

§Alias
Source

pub fn with_short_range_coulomb<R>( &mut self, omega: f64, func: impl FnOnce(&mut Self) -> R, ) -> R

Temporarily set the range separation parameter $\omega$ for Coulomb integrals (short range).

This function only accepts negative omega values, and is actually the alias to self.with_range_coulomb(-omega, func).

§Alias
Source

pub fn set_nuc_mod(&mut self, atm_id: usize, zeta: f64) -> &mut Self

Set the nuclear model for a given atom.

Source

pub fn get_rinv_zeta(&self) -> f64

Getter of the $\zeta$ parameter for nucleus model.

§See also
Source

pub fn set_rinv_zeta(&mut self, zeta: f64) -> &mut Self

Setter of the $\zeta$ parameter for nucleus model.

§See also
Source

pub fn with_rinv_zeta<R>( &mut self, zeta: f64, func: impl FnOnce(&mut Self) -> R, ) -> R

Temporarily set the $\zeta$ parameter for nucleus model.

§See also
Source

pub fn set_rinv_at_nucleus(&mut self, atm_id: usize) -> &mut Self

Set the origin to atom coordinate in evaluating $1/r$ for integrals.

§See also
Source

pub fn with_rinv_at_nucleus<R>( &mut self, atm_id: usize, func: impl FnOnce(&mut Self) -> R, ) -> R

Temporarily set the origin to atom coordinate in evaluating $1/r$ for integrals.

§Example (usual integral)
use libcint::prelude::*;
let mut cint_data = init_h2o_def2_tzvp();

let (out, _) = cint_data.integrate_row_major("int1e_rinv", None, None).into();
assert!((cint_fp(&out) - 51.806443495904794).abs() < 1e-10);

// set rinv origin to the second atom (first Hydrogen)
cint_data.with_rinv_at_nucleus(1, |data| {
    let (out, _) = data.integrate_row_major("int1e_rinv", None, None).into();
    assert!((cint_fp(&out) - 20.940503856155193).abs() < 1e-10);
});

PySCF equivalent:

mol = gto.Mole(atom="O; H 1 0.94; H 1 0.94 2 104.5", basis="def2-TZVP").build()
assert abs(lib.fp(mol.intor("int1e_rinv")) - 51.806443495904794) < 1e-10
with mol.with_rinv_at_nucleus(1):
    assert abs(lib.fp(mol.intor("int1e_rinv")) - 20.940503856155193) < 1e-10
§Example (ECP integral)
use libcint::prelude::*;
let mut cint_data = init_sb2me4_cc_pvtz();

let (out, _) = cint_data.integrate_row_major("ECPscalar_iprinvip", None, None).into();
assert!((cint_fp(&out) - 324.13737563392084).abs() < 1e-10);

// set rinv origin to the second atom (second Sb Antimony)
cint_data.with_rinv_at_nucleus(1, |data| {
    let (out, _) = data.integrate_row_major("ECPscalar_iprinvip", None, None).into();
    assert!((cint_fp(&out) - 302.6772698217352).abs() < 1e-10);
});

PySCF equivalent:

// definition of mol, see function `init_sb2me4_cc_pvtz` in this crate
assert abs(lib.fp(mol.intor("ECPscalar_iprinvip")) - 324.13737563392084) < 1e-10
with mol.with_rinv_at_nucleus(1):
    assert abs(lib.fp(mol.intor("ECPscalar_iprinvip")) - 302.6772698217352) < 1e-10
§See also
Source

pub fn get_integral_screen(&self) -> f64

Source

pub fn set_integral_screen(&mut self, screen: f64) -> &mut Self

Source

pub fn with_integral_screen<R>( &mut self, screen: f64, func: impl FnOnce(&mut Self) -> R, ) -> R

Source

pub fn get_geom(&self) -> Vec<[f64; 3]>

Getter of the geometry of the molecule (in unit Bohr).

§See also
§Alias
Source

pub fn set_geom(&mut self, coords: &[[f64; 3]]) -> &mut Self

Setter of the geometry of the molecule (in unit Bohr).

§See also
Source

pub fn with_geom<R>( &mut self, coords: &[[f64; 3]], func: impl FnOnce(&mut Self) -> R, ) -> R

Temporarily set the geometry of the molecule (in unit Bohr).

§See also
Source

pub fn get_grids(&self) -> Vec<[f64; 3]>

Getter of the grids for int1e_grids related integrals (in unit Bohr).

§See also
Source

pub fn set_grids(&mut self, grids: &[[f64; 3]]) -> &mut Self

Setter of the grids for int1e_grids related integrals (in unit Bohr).

§See also
Source

pub fn try_clear_grids(&mut self) -> &mut Self

Try to clear the grids for int1e_grids related integrals.

If grids are at the end of env, they will be cleared. Otherwise, the grids will become dangling data.

§See also
Source

pub fn with_grids<R>( &mut self, grids: &[[f64; 3]], func: impl FnOnce(&mut Self) -> R, ) -> R

Temporarily set the grids for int1e_grids related integrals (in unit Bohr).

With this function and integrate or integrate_row_major, you can perform int1e_grids related integrals with custom grids.

§See also
Source§

impl CInt

Implementation of integral at higher API level (for advanced user usage).

Source

pub fn optimizer(&self, intor: &str) -> CIntOptimizer

Obtain integrator optimizer.

§PySCF equivalent

gto.moleintor.make_cintopt

§Panics
  • integrator not found
  • env field not properly initialized for ECP integrator (should call merge_ecpbas before this function)
Source

pub fn optimizer_f(&self, intor: &str) -> Result<CIntOptimizer, CIntError>

Obtain integrator optimizer.

This function is failable.

§See also

CInt::optimizer

Source

pub fn integrate_with_args( &self, args: IntegrateArgs<'_, f64>, ) -> CIntOutput<f64>

Perform integral by arguments from builder.

This is advanced integral function. Additionally to integrate, this function also allows you to specify

  • out: output buffer for integral result, if not specified, a new buffer will be allocated.
  • row_major: whether the output is in row-major order (default is false, which means column-major order).

This function is not very convenient to use, since rust does not allow named arguments.

§Example
use libcint::prelude::*;
let data = init_h2o_def2_tzvp();
let mut out_buffer = vec![0.0; 100000];
let shls_slice = [[0, data.nbas()], [0, data.nbas()], [5, 10]];

// col-major, the same memory layout to PySCF's 2/3-center integrals
let args = data.integrate_args_builder()
    .intor("int3c2e_ip2")
    .aosym("s2ij")
    .shls_slice(&shls_slice)
    .out(&mut out_buffer)
    .row_major(false)
    .build()
    .unwrap();
let output = data.integrate_with_args(args);
assert!(output.out.is_none());
assert_eq!(output.shape, [946, 19, 3]);
assert!((cint_fp(&out_buffer) - -15.467133235509742).abs() < 1e-10);

// row-major, the same shape to PySCF's integrals
let args = data.integrate_args_builder()
    .intor("int3c2e_ip2")
    .aosym("s2ij")
    .shls_slice(&shls_slice)
    .out(&mut out_buffer)
    .row_major(true)
    .build()
    .unwrap();
let output = data.integrate_with_args(args);
assert!(output.out.is_none());
assert_eq!(output.shape, [3, 946, 19]);
assert!((cint_fp(&out_buffer) - 16.69819847729145).abs() < 1e-10);

PySCF equivalent (out_buffer column-major, out row-major for 3-center integrals in PySCF):

mol = gto.Mole(atom="O; H 1 0.94; H 1 0.94 2 104.5", basis="def2-TZVP").build()
out_buffer = np.zeros(100000)
shls_slice = [0, mol.nbas, 0, mol.nbas, 5, 10]
out = mol.intor("int3c2e_ip2", aosym="s2ij", shls_slice=shls_slice, out=out_buffer)
assert abs(lib.fp(out_buffer) - -15.467133235509742) < 1e-10
assert abs(lib.fp(out) - 16.69819847729145) < 1e-10
§See also
Source

pub fn integrate_with_args_f( &self, args: IntegrateArgs<'_, f64>, ) -> Result<CIntOutput<f64>, CIntError>

Perform integral by arguments from builder, failable version.

§See also

CInt::integrate_with_args

Source

pub fn integrate_with_args_spinor( &self, args: IntegrateArgs<'_, Complex<f64>>, ) -> CIntOutput<Complex<f64>>

Perform integral by arguments from builder for spinor integrals.

§See also

CInt::integrate_with_args CInt::integrate_with_args_spinor_f

Source

pub fn integrate_with_args_spinor_f( &self, args: IntegrateArgs<'_, Complex<f64>>, ) -> Result<CIntOutput<Complex<f64>>, CIntError>

Perform integral by arguments from builder for spinor integrals, failable version.

§See also

CInt::integrate_with_args_spinor

Source

pub fn integrate_with_args_inner<F>( &self, args: IntegrateArgs<'_, F>, ) -> Result<CIntOutput<F>, CIntError>
where F: ComplexFloat + Send + Sync,

Source

pub fn integrate_cross_with_args( args: IntorCrossArgs<'_, f64>, ) -> CIntOutput<f64>

Perform cross integral with multiple CInt instances.

This function is similar to CInt::integrate_with_args, but it allows you to specify multiple CInt instances, which is useful for integrals with auxiliary basis sets.

Corresponding builder is CInt::integrate_cross_args_builder.

§See also
Source

pub fn integrate_cross_with_args_f<F>( args: IntorCrossArgs<'_, f64>, ) -> Result<CIntOutput<f64>, CIntError>

Perform cross integral with multiple CInt instances, failable version.

§See also

CInt::integrate_cross_with_args

Source

pub fn integrate_cross_with_args_spinor( args: IntorCrossArgs<'_, Complex<f64>>, ) -> CIntOutput<Complex<f64>>

Perform cross integral with multiple CInt instances for spinor integrals.

§See also

CInt::integrate_cross_with_args

Source

pub fn integrate_cross_with_args_spinor_f<F>( args: IntorCrossArgs<'_, Complex<f64>>, ) -> Result<CIntOutput<Complex<f64>>, CIntError>

Perform cross integral with multiple CInt instances for spinor integrals, failable version.

§See also

CInt::integrate_cross_with_args_spinor

Source

pub fn integrate_cross_with_args_inner<F>( args: IntorCrossArgs<'_, F>, ) -> Result<CIntOutput<F>, CIntError>
where F: ComplexFloat + Send + Sync,

Source§

impl CInt

Obtaining integrator and argument builder.

These functions are mostly not for basic users, but for internal use or advanced users. For basic users, you can use CInt::integrate (and CInt::integrate_spinor for spinor integrals) to evaluate integrals.

Source

pub fn get_integrator(intor: &str) -> Box<dyn Integrator>

Obtain integrator by name.

This function does not require CInt instance. Make it here only for convenience.

§Panics
  • integrator not found
Source

pub fn get_integrator_f(intor: &str) -> Result<Box<dyn Integrator>, CIntError>

Obtain integrator by name, failable version.

§See also
Source

pub fn integrate_args_builder(&self) -> IntegrateArgsBuilder<'static, f64>

Obtain the builder of arguments for advanced integral evaluation.

§See also
Source

pub fn integrate_args_builder_spinor( &self, ) -> IntegrateArgsBuilder<'static, Complex<f64>>

Obtain the builder of arguments for advanced integral evaluation for spinor integrals.

§See also
Source

pub fn integrate_cross_args_builder( &self, ) -> IntorCrossArgsBuilder<'static, f64>

Obtain the builder of arguments for cross integral evaluation.

§See also
Source

pub fn integrate_cross_args_builder_spinor( &self, ) -> IntorCrossArgsBuilder<'static, Complex<f64>>

Obtain the builder of arguments for cross integral evaluation

§See also
Source§

impl CInt

Implementation of integral at higher API level (legacy support).

Source

pub fn integral_s1<T>( &self, shls_slice: Option<&[[c_int; 2]]>, ) -> (Vec<f64>, Vec<usize>)
where T: Integrator + Default,

Legacy support for integral evaluation for rest_libcint.

This function can be replaced by CInt::integrate.

§Example
use libcint::prelude::*;
use libcint::ffi::cint_wrapper::int1e_ipkin;
let cint_data = init_h2o_def2_tzvp();

let (out, shape) = cint_data.integral_s1::<int1e_ipkin>(None);
assert_eq!(shape, [43, 43, 3]);
Source

pub fn integral_s1_spinor<T>( &self, shls_slice: Option<&[[c_int; 2]]>, ) -> (Vec<Complex<f64>>, Vec<usize>)
where T: Integrator + Default,

Legacy support for integral evaluation for rest_libcint with spinor integrals.

This function can be replaced by CInt::integrate_spinor.

Source

pub fn integral_s2ij<T>( &self, shls_slice: Option<&[[c_int; 2]]>, ) -> (Vec<f64>, Vec<usize>)
where T: Integrator + Default,

Legacy support for integral evaluation for rest_libcint with s2ij symmetry.

This function can be replaced by CInt::integrate.

§Example
use libcint::prelude::*;
use libcint::ffi::cint_wrapper::int3c2e_ip2;
let cint_data = init_h2o_def2_tzvp();

let (out, shape) = cint_data.integral_s2ij::<int3c2e_ip2>(None);
assert_eq!(shape, [946, 43, 3]);
Source

pub fn integral_s2ij_spinor<T>( &self, shls_slice: Option<&[[c_int; 2]]>, ) -> (Vec<Complex<f64>>, Vec<usize>)
where T: Integrator + Default,

Legacy support for integral evaluation for rest_libcint with s2ij symmetry and spinor integrals.

This function can be replaced by CInt::integrate_spinor.

Source

pub fn integral_inner<T, F>( &self, shls_slice: Option<&[[c_int; 2]]>, aosym: CIntSymm, ) -> (Vec<F>, Vec<usize>)

Source§

impl CInt

Merge ECP data for integral evaluation.

Source

pub fn merge_ecpbas(&self) -> CInt

Creates a new CIntData instance, with ECP integral information written to bas field, and properly initializes values in env field.

This function is not intended to be used directly by users. This function is often used internally for data preparation.

Source

pub fn decopule_ecpbas(&self) -> CInt

Decouples ECP data from the CInt instance, returning a new CInt instance that have basis data and ecp data separated.

This function is not intended to be used directly by users. This function is often used internally for data preparation.

Source

pub fn is_ecp_merged(&self) -> bool

Check whether the CInt instance has been merged with ECP data.

Source§

impl CInt

Implementation of integral at lower API level (integral preparation).

Source

pub fn check_shls_slice( &self, integrator: &dyn Integrator, shls_slice: &[[c_int; 2]], cint_symm: CIntSymm, ) -> Result<(), CIntError>

Check if the integral can be integrated with the given integrator.

§Example

Following examples always uses H2O/def2-tzvp basis set with spheric.

use libcint::prelude::*;
let cint_data = init_h2o_def2_tzvp();

Successful case:

let integrator = CInt::get_integrator("int2e");
let shls_slice = &[[3, 13], [3, 13], [0, 19], [0, 19]];
let check = cint_data.check_shls_slice(&*integrator, shls_slice, CIntSymm::S4);
assert!(check.is_ok());

Failed case (shls_slice not matching to cint_symm):

let integrator = CInt::get_integrator("int2e");
let shls_slice = &[[0, 15], [3, 12], [0, 19], [0, 19]]; // first two slices different
let check = cint_data.check_shls_slice(&*integrator, shls_slice, CIntSymm::S4);
assert!(check.is_err());

Failed case (number of shls_slice not matching to number of centers):

let integrator = CInt::get_integrator("int1e_ipkin");
let shls_slice = &[[0, 15], [0, 15], [0, 19]]; // thr3e slices, but integrator requires 2
let check = cint_data.check_shls_slice(&*integrator, shls_slice, CIntSymm::S2ij);
assert!(check.is_err());
Source

pub fn check_float_type<F>(&self) -> Result<(), CIntError>
where F: ComplexFloat,

Check if the float type is correct for the cint_type.

  • For Spheric and Cartesian, it should be f64.
  • For Spinor, it should be Complex<f64>.

Note that we only check size of type, instead of its real type.

Source

pub fn check_optimizer( &self, integrator: &dyn Integrator, optimizer: &CIntOptimizer, ) -> Result<(), CIntError>

Check if the optimizer is compatible with the integrator.

This check only involves that ECP and general integrals have different optimizers.

Source

pub fn cgto_shape( &self, shls_slice: &[[c_int; 2]], aosym: CIntSymm, ) -> Vec<usize>

Source

pub fn cgto_shape_s1(&self, shls_slice: &[[c_int; 2]]) -> Vec<usize>

Shape of integral (in atomic orbital basis, symmetry s1), for specified slices of shell, without integrator components.

This function does not check the validity of the shls_slice.

§Example
use libcint::prelude::*;
let cint_data = init_h2o_def2_tzvp();
let shls_slice = [[0, 15], [5, 19], [3, 12]];
let cgto_shape = cint_data.cgto_shape_s1(&shls_slice);
assert_eq!(cgto_shape, vec![37, 38, 29]);
Source

pub fn cgto_shape_s2ij(&self, shls_slice: &[[c_int; 2]]) -> Vec<usize>

Shape of integral (in atomic orbital basis, symmetry s2ij), for specified slices of shell, without integrator components.

This function does not check the validity of the shls_slice.

§Panics

This function only checks if the first two elements of shls_slice are the same. If not, it will panic.

§Example
use libcint::prelude::*;
let cint_data = init_h2o_def2_tzvp();
let shls_slice = [[0, 15], [0, 15], [3, 12]];
let cgto_shape = cint_data.cgto_shape_s2ij(&shls_slice);
assert_eq!(cgto_shape, vec![703, 29]);
Source

pub fn cgto_shape_s2kl(&self, shls_slice: &[[c_int; 2]]) -> Vec<usize>

Shape of integral (in atomic orbital basis, symmetry s2kl), for specified slices of shell, without integrator components.

This function does not check the validity of the shls_slice.

Source

pub fn cgto_shape_s4(&self, shls_slice: &[[c_int; 2]]) -> Vec<usize>

Shape of integral (in atomic orbital basis, symmetry s4), for specified slices of shell, without integrator components.

This function does not check the validity of the shls_slice.

Source

pub fn cgto_shape_s8(&self, shls_slice: &[[c_int; 2]]) -> Vec<usize>

Shape of integral (in atomic orbital basis, symmetry s8), for specified slices of shell, without integrator components.

This function does not check the validity of the shls_slice.

Source

pub fn cgto_locs(&self, shls_slice: &[[c_int; 2]]) -> Vec<Vec<usize>>

Obtain atomic orbital locations for integral, starting from 0 (instead of the first basis index mapped from first shell, or to say that is relative).

This function will be used when coping small blocks of integral tensors into large output tensor.

§Example
use libcint::prelude::*;
let cint_data = init_h2o_def2_tzvp();
let shls_slice = [[0, 7], [2, 6], [15, 19]];
let cgto_locs = cint_data.cgto_locs(&shls_slice);
assert_eq!(cgto_locs, vec![
    vec![0, 1, 2, 3, 4, 5, 8, 11],
    vec![0, 1, 2, 3, 6],
    vec![0, 1, 2, 3, 6]
]);
Source

pub fn max_cache_size( &self, integrator: &dyn Integrator, shls_slice: &[[c_int; 2]], ) -> usize

Obtain cache size for integral.

If the shell slice is not known to you currently, just pass empty shls_slice = vec![], then it should give the maximum cache size for this molecule/intor.

Please also note that cache should be allocated per thread.

§PySCF equivalent

GTOmax_cache_size in fill_int2e.c

§Panics
  • Does not check the validity of the integrator.
  • Panic if shls_slice exceeds the number of shells in the molecule.
§Example
use libcint::prelude::*;
let cint_data = init_h2o_def2_tzvp();
let integrator = CInt::get_integrator("int2e_ip1");
let cache_size = cint_data.max_cache_size(&*integrator, &[]);
Source

pub fn max_buffer_size( &self, integrator: &dyn Integrator, shls_slice: &[[c_int; 2]], ) -> usize

Obtain maximum buffer size for integral.

§PySCF equivalent

GTOmax_shell_dim in fill_int2e.c for similar functionality (but different in result)

§Panics
  • Does not check the validity of the integrator.
  • Panic if shls_slice exceeds the number of shells in the molecule.
§Example
use libcint::prelude::*;
let cint_data = init_h2o_def2_tzvp();
let integrator = CInt::get_integrator("int3c2e_ip1");
let shls_slice = [[0, 7], [2, 6], [15, 19]];
let max_buffer_size = cint_data.max_buffer_size(&*integrator, &shls_slice);
assert_eq!(max_buffer_size, 81);
Source

pub fn get_optimizer(&self, integrator: &dyn Integrator) -> CIntOptimizer

Obtain optimizer for integral.

§Panics
  • Does not check the validity of the integrator.
Source

pub unsafe fn integral_block<F>( &self, integrator: &dyn Integrator, out: &mut [F], shls: &[c_int], shape: &[c_int], cint_opt: Option<&CIntOptimizer>, cache: &mut [f64], )
where F: ComplexFloat,

Smallest unit of electron-integral function from libcint.

This is not a safe wrapper function, though it is pure rust. Use with caution.

  • out - Output integral buffer, need to be allocated enough space before calling this function and properly offsetted.
  • shls - shell indices, which size should be n_center length.
  • cint_opt - optimizer that should be obtained before calling this function. If None, then no optimization will be performed and will pass null pointer.
  • shape - In general cases, it is not recommended to use. If output larger than 4GB, then libcint internal realization may overflow.
  • cache - cache buffer, need to be allocated enough space before calling this function; simply using vec![] should also works, which lets libcint manages cache and efficiency decreases. See Also CInt::max_cache_size for guide of properly allocate cache.
§Safety

This function does not check anything. Caller should handle checks:

  • Does not check type (float or complex) of out. Type check will be checked in caller.
  • Does not check shls length and values.
  • Does not check shape length and values.
  • Does not check whether cint_opt is ECP or general integrator, which may or may not corresponds to integrator’s type.
Source§

impl CInt

This impl block contains no items.

Implementation of integral at lower API level (crafting, col-major).

Source§

impl CInt

Implementation of grids implementation at lower API level

Source

pub fn max_cache_size_grids( &self, integrator: &dyn Integrator, shls_slice: &[[c_int; 2]], ) -> usize

Source§

impl CInt

This impl block contains no items.

Implementation of integral at lower API level (crafting, row-major).

Source§

impl CInt

Source

pub fn get_gto_eval_name_f( &self, eval_name: &str, ) -> Result<(Box<dyn GtoEvalAPI>, Option<CIntType>), CIntError>

Get GTO evaluator by name.

This function is fallible.

§See also
Source

pub fn get_gto_eval_name( &self, eval_name: &str, ) -> (Box<dyn GtoEvalAPI>, Option<CIntType>)

Get GTO evaluator by name.

§Returns
§See also
Source

pub fn gto_screen_index( &self, coords: &[[f64; 3]], shls_slice: Option<[usize; 2]>, nbins: Option<u8>, cutoff: Option<f64>, ) -> CIntOutput<u8>

Get GTO screening tabulation index (non0tab) on grids.

This will generate a screening table with shape (nbas, nblk), where $n_\mathrm{blk} = \lceil \frac{n_\mathrm{grid}}{\texttt{BLKSIZE}} \rceil$. BLKSIZE is a predefined constant 48.

The screening table represents whether each (basis shell, grid block) is significant enough to be evaluated. If the tabulated value is zero, then the corresponding (basis shell, grid block) pair can be skipped during GTO evaluation, within the cutoff threadhold that the API user provided.

§PySCF equivalent

pyscf.gto.eval_gto.make_screen_index; please note that blksize argument is not configurable for rust’s version, which is defined as a const BLKSIZE.

§Arguments
  • coords: Coordinates of grids, shape (ngrid, 3).
  • shls_slice: Slice of shells to evaluate. If None, evaluate all shells in the molecule.
  • nbins: Number of bins for screening. Default to NBINS or 100.
  • cutoff: Cutoff (GTO exponent without derivatives) for screening. Default to CUTOFF or 1e-22.
Source§

impl CInt

Source

pub fn gto_args_builder(&self) -> GtoArgsBuilder<'_, f64>

Create a builder for GTO evaluation arguments for CInt::eval_gto_with_args.

§See also
Source

pub fn eval_gto_with_args_f( &self, args: GtoArgs<'_, f64>, ) -> Result<CIntOutput<f64>, CIntError>

Evaluate GTO values on grids with given arguments.

§See also
Source

pub fn eval_gto_with_args(&self, args: GtoArgs<'_, f64>) -> CIntOutput<f64>

Evaluate GTO values on grids with given arguments.

For simple usage and more documentation, please refer to associated function eval_gto.

§PySCF equivalent

mol.eval_ao with full arguments. Please note that comp and ao_loc arguments in PySCF is not covered in rust’s version, since they are probably redundant.

§Example
use libcint::prelude::*;
let cint_data = init_h2o_def2_tzvp();

// generate a grid of 2048 points
let ngrid = 2048;
let coord: Vec<[f64; 3]> = (0..ngrid).map(|i| [(i as f64).sin(), (i as f64).cos(), (i as f64 + 0.5).sin()]).collect();
let args = cint_data.gto_args_builder()
    .eval_name("deriv1_sph")
    .coord(&coord)
    .cutoff(1e-15)    
    .build()
    .unwrap();
let (out, shape) = cint_data.eval_gto_with_args(args).into();
assert_eq!(shape, vec![2048, 43, 4]); // (ngrid, nao, ncomp)
§See also
Source

pub fn eval_gto_f( &self, eval_name: &str, coord: &[[f64; 3]], ) -> Result<CIntOutput<f64>, CIntError>

Evaluate GTO values on grids.

This function is fallible.

§See also
  • eval_gto for non-fallible counterpart.
Source

pub fn eval_gto(&self, eval_name: &str, coord: &[[f64; 3]]) -> CIntOutput<f64>

Evaluate GTO values on grids.

This function follows column-major convention.

For GTO value evaluation on grids, we do not provide another function for row-major convention, different to the case of integrate and integrate_row_major for electronic integrals.

We always put the grids to be the most contiguous dimension, then the atomic orbitals (basis), then the components. For spinors, the spin dimension is the least contiguous dimension.

We recommend the users who wish to have row-major output, only revert the list of shape (struct field of CIntOutput) after getting the output. We do not recommend API user of this function to perform explicit memory layout transposition; this will slow down your program: both in unnecessary memory bandwidth consumption, and cache efficiency reduction in DFT numerical integration.

§PySCF equivalent

mol.eval_ao(eval_name, coords)

§Arguments
  • eval_name: Evaluator name, such as "GTOval_sph_deriv1".
  • coord: Coordinates of grids, shape (ngrid, 3).
§Notes on argument eval_name

The eval_name can contain the following parts:

  • Component or operator: "deriv0", "deriv1", "deriv2", "deriv3", "ip", "ig", etc.
  • Shell type: "sph" or "cart". This affects the number of basis functions per shell. If not specified, the type will be determined by the current cint_type (struct field) of the CInt instance. This function does not support "spinor" type; please use eval_gto_spinor instead.
  • Prefix: "GTO" or "GTOval". This is for PySCF naming convention compatibility, not necessary.

See also get_gto_eval_name_f for the actual implementation.

§Output

Returns a CIntOutput<f64> for the evaluated GTO values, which contains

  • out (Vec<f64>): The output buffer for GTO values.
  • shape (Vec<usize>): The shape of output array in column-major order (ngrid, nao, ncomp).
§Example

The following example uses a pre-defined water molecule with def2-TZVP basis set.

The construction of CInt is not performed in this crate, but should be provided by user. We refer to function init_h2o_def2_tzvp for how to define a CInt instance.

use libcint::prelude::*;
let cint_data = init_h2o_def2_tzvp();

// generate a grid of 2048 points
let ngrid = 2048;
let coord: Vec<[f64; 3]> = (0..ngrid).map(|i| [(i as f64).sin(), (i as f64).cos(), (i as f64 + 0.5).sin()]).collect();
let (out, shape) = cint_data.eval_gto("GTOval_sph_deriv1", &coord).into();
assert_eq!(shape, vec![2048, 43, 4]); // (ngrid, nao, ncomp)
§Supported evaluators
Component$n_\mathrm{comp}$Description
deriv01GTO values
deriv14GTO values and derivatives to 1st order (useful for GGA/meta-GGA Fock matrix formulation)
deriv210GTO values and derivatives to 2nd order
deriv320GTO values and derivatives to 3rd order
deriv435GTO values and derivatives to 4th order
ip3derivative operator $\nabla$, or equivalently momemtum operator $\hat p$ scaled by imaginary unit $i$
ig3GIAO operator at 1st order $\hat U_\mathrm{g}$
ipig9Combined operator of ip and ig
ipr3derivative operator $\nabla$ multiplied by electronic position (taking atomic center as origin)
iprc3derivative operator $\nabla$ multiplied by electronic position (use certain common origin specified by set_common_origin)
sp1 × 4spinor sigma operator
ipsp3 × 4combined operator of ip and sp
ipipsp9 × 4combined operator of ip, ip, and sp

Note that for sp (sigma) related operators, for example ipsp, the component for non-spinor GTO is 3 × 4 or 12, but will be 3 for spinor GTO.

This function cannot handle spinor GTO evaluation

Due to rust’s strict type system, it is very difficult to handle both spinor and spheric/cartesian GTO evaluation in the same function. So spinor GTO evaluation should be called by eval_gto_spinor, which output is Complex<f64>.

let (out, shape) = cint_data.eval_gto("GTOval_spinor_deriv2", &coord).into();
// InvalidValue: Spinor type is not supported
§See also
Source§

impl CInt

Source

pub fn gto_args_builder_spinor(&self) -> GtoArgsBuilder<'_, Complex<f64>>

Create a builder for GTO evaluation arguments for spinor GTO evaluation.

§See also
Source

pub fn eval_gto_with_args_spinor_f( &self, args: GtoArgs<'_, Complex<f64>>, ) -> Result<CIntOutput<Complex<f64>>, CIntError>

Evaluate spinor GTO values on grids with given arguments.

§See also
Source

pub fn eval_gto_with_args_spinor( &self, args: GtoArgs<'_, Complex<f64>>, ) -> CIntOutput<Complex<f64>>

Evaluate spinor GTO values on grids with given arguments.

§See also
Source

pub fn eval_gto_spinor_f( &self, eval_name: &str, coord: &[[f64; 3]], ) -> Result<CIntOutput<Complex<f64>>, CIntError>

Evaluate spinor GTO values on grids.

This function is fallible.

§See also
Source

pub fn eval_gto_spinor( &self, eval_name: &str, coord: &[[f64; 3]], ) -> CIntOutput<Complex<f64>>

Evaluate spinor GTO values on grids.

For non-spinor GTO evaluation, please use eval_gto.

This function will return complex-valued GTO values, with shape (ngrid, nao, ncomp, 2) in column-major order, where the last dimension of size 2 represents the two spinor components (spin-up and spin-down).

§Example
use libcint::prelude::*;
let cint_data = init_h2o_def2_tzvp();
let ngrid = 2048;
let coord: Vec<[f64; 3]> = (0..ngrid).map(|i| [(i as f64).sin(), (i as f64).cos(), (i as f64 + 0.5).sin()]).collect();
let (out, shape) = cint_data.eval_gto_spinor("GTOval_spinor_deriv1", &coord).into();
assert_eq!(shape, vec![2048, 86, 4, 2]); // (ngrid, nao, ncomp, 2)
let (out, shape) = cint_data.eval_gto_spinor("GTOval_spinor_ipsp", &coord).into();
assert_eq!(shape, vec![2048, 86, 3, 2]); // (ngrid, nao, ncomp, 2)
§See also

Trait Implementations§

Source§

impl Add for &CInt

Concatenating two molecules for integral.

Source§

type Output = CInt

The resulting type after applying the + operator.
Source§

fn add(self, mol2: &CInt) -> CInt

Performs the + operation. Read more
Source§

impl Clone for CInt

Source§

fn clone(&self) -> CInt

Returns a duplicate of the value. Read more
1.0.0§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for CInt

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl From<CInt> for CIntSerdeIntermediate

Source§

fn from(cint_data: CInt) -> Self

Converts to this type from the input type.
Source§

impl From<CIntSerdeIntermediate> for CInt

Source§

fn from(cint_data: CIntSerdeIntermediate) -> Self

Converts to this type from the input type.
Source§

impl PartialEq for CInt

Source§

fn eq(&self, other: &CInt) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl StructuralPartialEq for CInt

Auto Trait Implementations§

§

impl Freeze for CInt

§

impl RefUnwindSafe for CInt

§

impl Send for CInt

§

impl Sync for CInt

§

impl Unpin for CInt

§

impl UnwindSafe for CInt

Blanket Implementations§

§

impl<T> Any for T
where T: 'static + ?Sized,

§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<T> Borrow<T> for T
where T: ?Sized,

§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
§

impl<T> BorrowMut<T> for T
where T: ?Sized,

§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> CloneToUninit for T
where T: Clone,

§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
§

impl<T> From<T> for T

§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T, U> Into<U> for T
where U: From<T>,

§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
§

impl<T> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.