GSoC 2025: Transformed Cubic Grids
Description
One disadvantage of Becke-style molecular grids is that, due to overlapping atomic grids, there are numerous grid points that have very small, but nonnegligible, weights. Our strategy to overcome this issue is to use a cubic grid, but transform it to real space in such a way that points are concentrated where the integrands of interest are large and/or rapidly changing. The goal of this project is add this functionality to Grid. One nice facet of this approach is that it is easy to adaptively refine a cubic grid, and ergo a transformed cubic grid. This allows for adaptive quadrature to be implemented without too much pain.
:books: Package Description and Impact
Grid is a pure Python library for numerical integration, interpolation and differentiation of interest for the quantum chemistry community.
:construction_worker: What will you do?
A more detailed description of this project is available in issue #15 . The basic idea is to take a cubic grid, and then perform a transformation based on a probability distribution function, using the conditional distribution method.
:checkered_flag: Expected Outcomes
- Refresh pull request #96 and merge it.
- Implement adaptive transformed cubic grid.
- Write comprehensive tests and documentation for all new functionality.
- Write tutorial Jupyter notebooks that show how to use the new functionality.
| Required skills | Python, OOP |
| Preferred skills | Be comfortable with math and numerical algorithms. Experience with scientific programming can help |
| Project size | 175 hours, Medium |
| Difficulty | Medium 🤔 |
:raising_hand: Mentors
| Marco Martínez-González | mmg870630_at_gmail_dot_com | @marco-2023 |
| Farnaz Heidar-Zadeh | farnaz_dot_heidarzadeh_at_queensu_dot_ca | @FarnazH |
| Ali Tehrani | 19at27_at_queensu_dot_ca | @Ali-Tehrani |
Hi can I work on this?
Hi can I work on this?
Of course. We have not yet heard from GSoC about approval (or not) for this year. Presuming you would like to do it as part of GSoC, you should look at the guidelines. We always have a few people who end up taking on a GSoC project without actually doing GSoC, so we are happy to support that too.
Note that we cannot promise anyone a GSoC position or anything of that sort. We can only say we support anyone who wishes to contribute to the best of our ability and capacity.
Thank you! I am always looking to work on coding projects as a hobby. GSoC or not, I am still willing.
Hey mentors, How can I work on this project.? Please guide me.
The first step is to read the guidelines. Then you'll need to start to understand the project, looking at the algorithm and the existing code, so that you can write a proposal.
hey @PaulWAyers , Thank you for the guidance! I'll begin by reviewing the guidelines and exploring the existing implementation, especially the transformation approach for cubic grids. I'll also go through issue #15 and PR #96 to understand the current state and areas for improvement. I wanted to clarify—do I need to make a contribution to the project before submitting my proposal, or is a well-drafted proposal sufficient? Let me know how I should proceed. Looking forward to your guidance on this
A well-drafted proposal is submitted. Sometimes someone has made a pull request, which can be useful, but as I recall last year the two successful applicants had not made a pull request (certainly not a merged pull request) at the time they were accepted by GSoC. In general, we are mostly looking for skilled applicants who have the ability to write cogent proposals that demonstrate understanding and perspective on the problem. The example proposal linked to at https://qcdevs.org/join/qcdevs_gsoc/ is useful.
Hey @PaulWAyers , thanks for sharing this! It’s really helpful to know that a well-written proposal is the main focus rather than making a PR early on. I’ve been diving into issue #15 and PR #96 to get a better understanding of how the transformation approach is currently implemented and where improvements can be made. I’ll make sure my proposal reflects a solid grasp of the problem and possible solutions. Do you think it would be useful to highlight any specific edge cases or challenges in the transformation process? Also, if there are key aspects you’d recommend emphasizing in the proposal, I’d love to hear your thoughts. Looking forward to your insights!
The transformation process is, I believe, relatively straightforward. The edge case I know is when the point is not bracketed, and one needs to bracket it. (The other edge case is where the solver doesn't converge, which can always be fixed by increasing the number of iterations or switching to a brute-strength solver like the bisection method). Neither should not be an issue in the adaptive algorithm, where a (very!) good guess is always available for the solver.
GSOC project
Phase 1 Steps:
I'll fix the merge conflicts, I tried to add @tutou2356 to the issue assignee, but couldn't.
- Obtain the promolecular coefficients and exponents from theochem/BFit. i) Download kl_slsqp_results.npz, and figure out how to read it using numpy. ii) Create a new python script (or jupyter notebook) and figure out how to add the coefficients/exponents to _PromolParams. iii) Provide the notebook/script to us for review, or any questions.
- Create integration tests to make sure the code integrates to the correct number of electrons
i) Create five examples by choosing one of each systems: an atom, a homonuclear diatomic, a heteronuclear diatomic and a small molecular system (e.g., methane).
ii) Review this following test on how to use Promolecular transform to integrate any function.
iii) Obtain the electron densities of the systems using either AtomDB or obtain wavefunction (e.g. FCHK) and use GBasis.
iv) Integrate the electron densities, and report the following using a table or plot:
- How long it took to transform the grid, i.e. make the
CubicProTransformclass. - What the error is in integrating the electron density to the correct number of electrons in relation to the number of points of the Cubic Grid.
- How long it took to transform the grid, i.e. make the
- Based on your experience, potentially provide us recommendations on how to improve the API, or usage, or the readability of the code, or how to make it faster.
@FarnazH did some work merging with the old code base last week. Good to start from that. It was working, though the bracketing was suboptimal as I recall.
Ah sorry, didn't know, and I already did a merge to the pull-request, before you commented. Farnaz can either force-push, or merge on-top of it. The bracketing and root-finding could definitely be improved upon. I fixed the bug on the bracketing, and left an easy TODO to make it slightly more efficient.
Hi Ali, Paul
Thank you for outlining the Phase-1 roadmap and for the merge-conflict help. I have started reviewing PR #96 and the current CubicProTransform implementation, and I’m also looking for Farnaz’s branch that Paul mentioned so I can pull in any additional fixes before I begin.
Phase 2 Steps
Hi @tutou2356,
After consulting with @marco-2023, the next phase two is to implement the ability to adaptive Uniform Grid. The goal is to first implement a function called refinement inside UniformGrid. This function takes points whose error is high, and adds new neighbouring points until the error is less than some tolerance. Afterwards, the goal is to study how integration accuracy and computational time improves from using this adaptive grid. Please make a new pull-request to implement this.
- Find points that need more refinement by looking at some error. One easy choice of error is to take the finite difference approximation of the gradient of the integrand, and multiply it by the spacing of the grid. This identifies points whose change in integrand is high. Feel free to use other errors measures but you will need to justify it. To identify neighbours to a given point, please use this method.
- For each of those points with high error:
- Push the point (and its half‑spacing in each dimension) onto the stack/queue.
- Delete all points with high error from
grid.pointsandgrid.weights. They will be added later. - While the stack/queue is not empty:
- Pop a
(grid_point, spacing)pair. - Compute its neighbours (e.g. in 3D it would have six neighbours: up, down, left, right, front, and back) by doing $x \pm (spacing / 2) a_i$, where $a_i$ is the ith axis of the grid.
- Check the error at the point. Note that depending on the error measure, you will need to track its neighbours.
- If the error is within tolerance:
- Append the point to
grid.pointsand recompute its weight ingrid.weights.
- Append the point to
- Else:
- Push the point
(point, spacing/2)and all neighbours(neighbour, spacing/2)back onto the stack/queue.
- Push the point
- If the error is within tolerance:
- Pop a
- Update
grid.pointsandgrid.weights, then proceed as normal.
If there are any problems with this, or if you have any questions, please email or use the discussion board.