PR-8: Feat- Bind gradient and GIAO/magnetic integrals + cleanup - #256
Draft
San1357 wants to merge 27 commits into
Draft
PR-8: Feat- Bind gradient and GIAO/magnetic integrals + cleanup #256San1357 wants to merge 27 commits into
San1357 wants to merge 27 commits into
Conversation
added 17 commits
June 26, 2026 10:56
Contributor
There was a problem hiding this comment.
Pull request overview
This PR extends gbasis’s libcint-backed integration layer by adding new C shell-loop (array) bindings for gradient building-block integrals and GIAO/magnetic integrals, along with corresponding tests and some wrapper cleanup.
Changes:
- Added C-loop array wrappers (with optimizer support) for gradient and GIAO/magnetic 1e integrals in
libcint_wrap.c. - Exposed the new bindings in
gbasis.integrals.libcint.CBasis, and updated existing C-loop calls to use the new*_integral_arrayentry points. - Expanded
tests/test_libcint.pywith new parameterized tests for gradient and GIAO bindings and updated shared-library presence detection.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 9 comments.
| File | Description |
|---|---|
tests/test_libcint.py |
Adds/updates tests for new gradient and GIAO/magnetic C bindings and broadens the libcint shared-library glob. |
gbasis/integrals/src/libcint_wrap.c |
Implements new optimizer-backed C shell-loop array wrappers for additional 1e integrals (gradient + GIAO/magnetic) and refactors wrapper macros. |
gbasis/integrals/libcint.py |
Wires new C-loop entry points into CBasis and adds new public methods for gradient and GIAO/magnetic integrals. |
CMakeLists.txt |
Adds libcint include directory to the extension build include paths. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+10
to
+14
| # to Remove 1 | ||
| from ctypes import CDLL, POINTER, Structure, cdll, byref, c_int, c_double | ||
|
|
||
| from itertools import chain | ||
| # to Remove 2 | ||
| # from itertools import chain |
Comment on lines
24
to
+27
| from scipy.special import factorial | ||
|
|
||
| from gbasis.utils import factorial2 | ||
| # to Remove 3 | ||
| # from gbasis.utils import factorial2 |
Comment on lines
+135
to
+136
| /* Optimizer macro using token pasting */ | ||
| #define MAKE_OPTIMIZER(func) c##func##_optimizer |
Comment on lines
+1410
to
+1430
| def gradient_rinv(self): | ||
| r""" | ||
| Compute the gradient of 1/r integrals (i∇ rinv). | ||
|
|
||
| Returns | ||
| ------- | ||
| out : np.ndarray(Nbasis, Nbasis, dtype=float) | ||
| Gradient 1/r integral array. | ||
| """ | ||
| out = np.zeros((self.nbfn, self.nbfn), dtype=c_double, order="F") | ||
| libcint_bindings.iprinv_integral_array( | ||
| out, | ||
| self.natm, | ||
| self.atm, | ||
| self.nbas, | ||
| self.bas, | ||
| self.env, | ||
| self._offs, | ||
| self.nbfn, | ||
| ) | ||
| return out |
Comment on lines
+1566
to
+1583
| 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_array( | ||
| val, | ||
| self.natm, | ||
| self.atm, | ||
| self.nbas, | ||
| self.bas, | ||
| self.env, | ||
| self._offs, | ||
| self.nbfn, | ||
| ) | ||
| val *= -charge | ||
| out[:, :, icharge] = val | ||
| return out |
Comment on lines
+1605
to
+1608
| Notes | ||
| ----- | ||
| Uses the C shell-loop bindings for dipole, quadrupole, and octupole | ||
| integrals internally. Supports up to 3rd order moments. |
| and ``.gradient_rinv()`` methods which are the building blocks | ||
| for computing nuclear coordinate gradients. | ||
| """ | ||
| from gbasis.integrals.libcint import ELEMENTS, CBasis |
| integrals, we verify shape and that results are finite and | ||
| non-trivially zero for multi-atom systems. | ||
| """ | ||
| from gbasis.integrals.libcint import ELEMENTS, CBasis |
Comment on lines
+680
to
+681
| # Finiteness check — no NaN or Inf | ||
| assert np.all(np.isfinite(lc_int)), f"{integral} contains NaN or Inf" |
added 6 commits
July 11, 2026 17:54
added 2 commits
July 12, 2026 09:22
msricher
approved these changes
Jul 13, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR adds C-loop bindings for gradient building-block integrals and GIAO/magnetic integrals as discussed with mentors.
Changes
New C-loop bindings — Gradient integrals (
libcint_wrap.c+libcint.py)Building blocks for nuclear coordinate gradients:
gradient_kinetic()—int1e_ipkin_sphgradient_nuclear()—int1e_ipnuc_sphgradient_rinv()—int1e_iprinv_sphNew C-loop bindings — GIAO/magnetic integrals (
libcint_wrap.c+libcint.py)Building blocks for NMR/magnetic property calculations:
ia01p()—int1e_ia01p_sphircxp()—int1e_cg_irxp_sphiking()—int1e_igkin_sphiovlpg()—int1e_igovlp_sphinucg()—int1e_ignuc_sphTests (
tests/test_libcint.py)test_c_gradient_integral— 45 tests for gradient integralstest_c_giao_integral— 75 tests for GIAO/magnetic integralsNotes
DEFINE_INT1E_LOOP_FNmacro with token pasting optimizerRelated