PR-7 — feat: add C shell-loop bindings for point_charge, moment, momentum & tests - #255
PR-7 — feat: add C shell-loop bindings for point_charge, moment, momentum & tests#255San1357 wants to merge 13 commits into
Conversation
msricher
left a comment
There was a problem hiding this comment.
Good, just see comments.
| DEFINE_INTEGRAL_INT1e(octupole_sph, int1e_rrr_sph) | ||
| DEFINE_INT1E_ARRAY_FN(overlap_sph, int1e_ovlp_sph) |
There was a problem hiding this comment.
Can we keep the name INT1E_ARRAY consistently across files instead of INT1E_SHELLOOP? Names should generally be descriptive of their purpose rather than their implementation details.
| int *offs = (int *) PyArray_GETPTR1(offs_arr, 0); | ||
|
|
||
| int shls[4]; | ||
| double buf[100000] = {0}; |
There was a problem hiding this comment.
Allocate this array dynamically, with whatever size you need, which you can calculate.
Instead of
double buf[1000000] = {0};
/* do work... */have something like this:
#include <stdlib.h>;
/* ... */;
double *buf = calloc(CALCULATED_SIZE, sizeof(double));
/* do work... */;
free(buf);
return WHATEVER;There was a problem hiding this comment.
Pull request overview
This PR extends the gbasis.integrals.libcint.CBasis API with additional high-level methods and C-backed shell-loop implementations, and expands the test suite to validate the new C shell-loop pathways against existing GBasis and libcint-based reference implementations.
Changes:
- Added new
CBasisconvenience methods (point_charge,moment,electron_repulsion) and updatedmomentum()to return the full 3-component complex result consistent withmomentum_integral(). - Added a new C extension entry point
eri_shellloopfor 2-electron ERI shell-loop evaluation. - Expanded
tests/test_libcint.pywith new C shell-loop correctness tests and broadened shared-library discovery.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 8 comments.
| File | Description |
|---|---|
tests/test_libcint.py |
Adds new parametrized tests covering C shell-loop methods and updates shared-library detection globbing. |
gbasis/integrals/src/libcint_wrap.c |
Introduces eri_shellloop and renames/extends C macro wrappers for libcint bindings. |
gbasis/integrals/libcint.py |
Adds/updates CBasis methods (momentum, point_charge, moment, electron_repulsion) to expose the new functionality from Python. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| shls[3] = lshl; | ||
| int s_off = offs[lshl]; | ||
| int2e_sph(buf, NULL, shls, atm, natm, bas, nbas, env, NULL, NULL); |
| out = np.zeros((self.nbfn, self.nbfn, len(point_charges)), dtype=c_double, order='F') | ||
| for icharge, (coord, charge) in enumerate(zip(point_coords, point_charges)): | ||
| # Set inv_origin in env for this charge | ||
| self.env[4:7] = coord | ||
| val = np.zeros((self.nbfn, self.nbfn), dtype=c_double, order='F') | ||
| libcint_bindings.rinv_integral_shellloop( | ||
| val, self.natm, self.atm, self.nbas, | ||
| self.bas, self.env, self._offs, self.nbfn | ||
| ) | ||
| val *= -charge | ||
| out[:, :, icharge] = val | ||
| return out |
| if origin is None: | ||
| origin = np.zeros(3) | ||
| out = np.zeros((self.nbfn, self.nbfn, len(orders)), dtype=np.float64) | ||
| for i, order in enumerate(orders): | ||
| self.env[1:4] = origin | ||
| if sum(order) == 0: | ||
| out[:, :, i] = self.overlap() | ||
| else: | ||
| out[:, :, i] = self._moments[tuple(order)](origin=origin) | ||
| return out |
| Notes | ||
| ----- | ||
| Uses the C shell-loop bindings for dipole, quadrupole, and octupole | ||
| integrals internally. Supports up to 3rd order moments. | ||
|
|
| out = np.zeros((self.nbfn, self.nbfn, self.nbfn, self.nbfn), dtype=c_double) | ||
| libcint_bindings.eri_shellloop( | ||
| out, self.natm, self.atm, self.nbas, | ||
| self.bas, self.env, self._offs, self.nbfn | ||
| ) | ||
| return out |
| The two-electron repulsion integral between basis functions | ||
| :math:`\phi_i`, :math:`\phi_j`, :math:`\phi_k`, and :math:`\phi_l` | ||
| is defined as: | ||
|
|
||
| .. math:: | ||
| g_{ijkl} = \langle \phi_i \phi_j | \frac{1}{r_{12}} | \phi_k \phi_l \rangle | ||
|
|
| sides here come from libcint. | ||
|
|
||
| """ | ||
| from gbasis.integrals.libcint import ELEMENTS, CBasis |
| # 2-electron ERI: C shell-loop vs. make_int2e shell-loop | ||
| npt.assert_allclose( | ||
| lc_basis.electron_repulsion(), | ||
| lc_basis.electron_repulsion_integral(), | ||
| atol=1e-8, | ||
| rtol=1e-8, | ||
| ) |
Changes
point_charge()— usesrinv_integral_shellloopinternally per charge ~13x speedupmoment()— uses_momentsdict internallymomentum()to return full 3-component complex array (now matchesmomentum_integral())New Tests (test_libcint.py)
test_c_shellloop_integral— tests all C shell-loop methods against GBasis Python implementations:test_c_shellloop_matches_make_int1e— cross-checks C shell-loop directly against make_int1e/make_int2e on same CBasis instanceRelated
LibcintandGBasis#229Test verifications: