Skip to content

PR-8: Feat- Bind gradient and GIAO/magnetic integrals + cleanup - #256

Draft
San1357 wants to merge 27 commits into
theochem:san1357-devfrom
San1357:pr-8/bind-all-libcint
Draft

PR-8: Feat- Bind gradient and GIAO/magnetic integrals + cleanup #256
San1357 wants to merge 27 commits into
theochem:san1357-devfrom
San1357:pr-8/bind-all-libcint

Conversation

@San1357

@San1357 San1357 commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

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_sph
  • gradient_nuclear()int1e_ipnuc_sph
  • gradient_rinv()int1e_iprinv_sph

New C-loop bindings — GIAO/magnetic integrals (libcint_wrap.c + libcint.py)

Building blocks for NMR/magnetic property calculations:

  • ia01p()int1e_ia01p_sph
  • ircxp()int1e_cg_irxp_sph
  • iking()int1e_igkin_sph
  • iovlpg()int1e_igovlp_sph
  • inucg()int1e_ignuc_sph

Tests (tests/test_libcint.py)

  • test_c_gradient_integral — 45 tests for gradient integrals
  • test_c_giao_integral — 75 tests for GIAO/magnetic integrals
  • All 120 new tests passing

Notes

  • All new bindings use DEFINE_INT1E_LOOP_FN macro with token pasting optimizer
  • Full gradient assembly (chain rule, MO basis) is out of scope — deferred to GOpt/qc-mean-field

Related

@San1357
San1357 requested a review from msricher July 8, 2026 11:42

@msricher msricher left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good to merge!

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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_array entry points.
  • Expanded tests/test_libcint.py with 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 thread gbasis/integrals/libcint.py Outdated
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.
Comment thread tests/test_libcint.py
and ``.gradient_rinv()`` methods which are the building blocks
for computing nuclear coordinate gradients.
"""
from gbasis.integrals.libcint import ELEMENTS, CBasis
Comment thread tests/test_libcint.py
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 thread tests/test_libcint.py Outdated
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"
@San1357
San1357 requested a review from msricher July 13, 2026 16:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants