Skip to content

Commit b7c99e1

Browse files
committed
convert README.rst to README.md
1 parent b80ec57 commit b7c99e1

3 files changed

Lines changed: 333 additions & 366 deletions

File tree

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ authors = ["Radovan Bast <[email protected]>"]
55
description = "Numerical integration grid for molecules."
66
license = "MPL-2.0"
77
edition = "2018"
8-
readme = "README.rst"
8+
readme = "README.md"
99
homepage = "https://github.com/dftlibs/numgrid/"
1010

1111
[lib]

README.md

Lines changed: 332 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,332 @@
1+
[![test status](https://github.com/dftlibs/numgrid/workflows/Test/badge.svg)](https://github.com/dftlibs/numgrid/actions)
2+
[![license badge](https://img.shields.io/badge/license-%20GPL-blue.svg)](LICENSE)
3+
[![link to PyPI](https://badge.fury.io/py/numgrid.svg)](https://badge.fury.io/py/numgrid)
4+
[![link to Zenodo/DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.1470276.svg)](https://doi.org/10.5281/zenodo.1470276)
5+
6+
- [Changelog](CHANGES.md)
7+
- Licensed under [MPL v2.0](LICENSE) (except John
8+
Burkardt’s Lebedev code which is redistributed under LGPL v3.0)
9+
10+
11+
# Numgrid
12+
13+
Numgrid is a library that produces numerical integration grid for
14+
molecules based on atom coordinates, atom types, and basis set
15+
information. This library provides Rust and Python bindings.
16+
17+
18+
## Who are the people behind this code?
19+
20+
Authors
21+
- Radovan Bast
22+
23+
Contributors
24+
- Roberto Di Remigio (OS X testing, streamlined Travis testing, better
25+
C++, error handling)
26+
27+
For a list of all the contributions see
28+
https://github.com/dftlibs/numgrid/contributors.
29+
30+
31+
### Acknowledgements
32+
33+
- Simon Neville (reporting issues)
34+
- Jaime Axel Rosal Sandberg (reporting issues)
35+
36+
This tool uses SPHERE_LEBEDEV_RULE, a C library written by John Burkardt which
37+
computes a Lebedev quadrature rule over the surface of the unit sphere in 3D,
38+
see also:
39+
http://people.sc.fsu.edu/~jburkardt/c_src/sphere_lebedev_rule/sphere_lebedev_rule.html
40+
41+
This library uses and acknowledges the
42+
MolSSI BSE (https://molssi-bse.github.io/basis_set_exchange/),
43+
which is a rewrite of the Basis Set Exchange
44+
(https://bse.pnl.gov/bse/portal) and is a collaboration between the Molecular
45+
Sciences Software Institute (http://www.molssi.org) and the Environmental
46+
Molecular Sciences Laboratory (https://www.emsl.pnl.gov).
47+
48+
49+
### Citation
50+
51+
If you use this tool in a program or publication, please acknowledge its
52+
author(s)
53+
```bibtex
54+
@misc{numgrid,
55+
author = {Bast, Radovan},
56+
title = {Numgrid: Numerical integration grid for molecules},
57+
month = {1},
58+
year = {2021},
59+
publisher = {Zenodo},
60+
version = {v2.1.0},
61+
doi = {10.5281/zenodo.1470276},
62+
url = {https://doi.org/10.5281/zenodo.1470276}
63+
}
64+
65+
@misc{sphere_lebedev_rule,
66+
author = {Burkardt, John},
67+
title = {SPHERE_LEBEDEV_RULE: Quadrature Rules for the Unit Sphere},
68+
year = {2010},
69+
url = {https://people.sc.fsu.edu/~jburkardt/c_src/sphere_lebedev_rule/sphere_lebedev_rule.html}
70+
}
71+
```
72+
73+
I kindly ask you to also cite the latter since Numgrid is basically a "shell"
74+
around SPHERE_LEBEDEV_RULE, with added radial integration and molecular
75+
partitioning.
76+
77+
78+
### Would you like to contribute?
79+
80+
Yes please! Please follow [this excellent
81+
guide](http://www.contribution-guide.org). We do not require any formal
82+
copyright assignment or contributor license agreement. Any contributions
83+
intentionally sent upstream are presumed to be offered under terms of the
84+
Mozilla Public License Version 2.0.
85+
86+
87+
## Requirements
88+
89+
- Python (3.8 - 3.12).
90+
- For the Rust version: A [Rust installation](https://www.rust-lang.org/tools/install).
91+
92+
93+
## Installation
94+
95+
96+
### Installing via pip
97+
98+
```bash
99+
python -m pip install numgrid
100+
```
101+
102+
103+
### Building from sources and testing
104+
105+
Building the code:
106+
```bash
107+
cargo build --release
108+
```
109+
110+
Testing the Rust interface:
111+
```bash
112+
cargo test --release
113+
```
114+
115+
Running also the longer tests:
116+
```bash
117+
cargo test --release -- --ignored
118+
```
119+
120+
Testing the Python layer:
121+
```bash
122+
pip install -r requirements.txt # ideally into a virtual environment
123+
maturin develop
124+
pytest tests/test.py
125+
```
126+
127+
128+
## API
129+
130+
131+
### The API changed
132+
133+
The API changed (sorry!) for easier maintenance and simpler use:
134+
135+
- No initialization or deallocation necessary.
136+
137+
- One-step instead of two steps (since the radial grid generation time is
138+
negligible compared to space partitioning, it did not make sense anymore to
139+
separate these steps and introduce a state).
140+
141+
- `alpha_min` is given as dictionary which saves an argument and simplifies
142+
explaining the API.
143+
144+
- The library now provides Rust and Python bindings. It used to provide C and
145+
Fortran bindings. The C/Fortran code lives on the [cpp-version branch](https://github.com/dftlibs/numgrid/tree/cpp-version). I might bring the
146+
C interfaces back into the Rust code if there is sufficient interest/need.
147+
148+
149+
### Units
150+
151+
Coordinates are in bohr.
152+
153+
154+
### Python example
155+
156+
As an example let us generate a grid for the water molecule:
157+
```python
158+
import numgrid
159+
160+
radial_precision = 1.0e-12
161+
min_num_angular_points = 86
162+
max_num_angular_points = 302
163+
164+
proton_charges = [8, 1, 1]
165+
166+
center_coordinates_bohr = [(0.0, 0.0, 0.0), (1.43, 0.0, 1.1), (-1.43, 0.0, 1.1)]
167+
168+
# cc-pVDZ basis
169+
alpha_max = [
170+
11720.0, # O
171+
13.01, # H
172+
13.01, # H
173+
]
174+
alpha_min = [
175+
{0: 0.3023, 1: 0.2753, 2: 1.185}, # O
176+
{0: 0.122, 1: 0.727}, # H
177+
{0: 0.122, 1: 0.727}, # H
178+
]
179+
180+
for center_index in range(len(center_coordinates_bohr)):
181+
# atom grid using explicit basis set parameters
182+
coordinates, weights = numgrid.atom_grid(
183+
alpha_min[center_index],
184+
alpha_max[center_index],
185+
radial_precision,
186+
min_num_angular_points,
187+
max_num_angular_points,
188+
proton_charges,
189+
center_index,
190+
center_coordinates_bohr,
191+
hardness=3,
192+
)
193+
194+
# atom grid using basis set name
195+
# this takes a second or two for the REST API request
196+
coordinates, weights = numgrid.atom_grid_bse(
197+
"cc-pVDZ",
198+
radial_precision,
199+
min_num_angular_points,
200+
max_num_angular_points,
201+
proton_charges,
202+
center_index,
203+
center_coordinates_bohr,
204+
hardness=3,
205+
)
206+
207+
# radial grid (LMG) using explicit basis set parameters
208+
radii, weights = numgrid.radial_grid_lmg(
209+
alpha_min={0: 0.3023, 1: 0.2753, 2: 1.185},
210+
alpha_max=11720.0,
211+
radial_precision=1.0e-12,
212+
proton_charge=8,
213+
)
214+
215+
# radial grid (LMG) using basis set name
216+
radii, weights = numgrid.radial_grid_lmg_bse(
217+
basis_set="cc-pVDZ",
218+
radial_precision=1.0e-12,
219+
proton_charge=8,
220+
)
221+
222+
# radial grid with 100 points using Krack-Koster approach
223+
radii, weights = numgrid.radial_grid_kk(num_points=100)
224+
225+
# angular grid with 14 points
226+
coordinates, weights = numgrid.angular_grid(num_points=14)
227+
```
228+
229+
230+
### Notes and recommendations
231+
232+
- The smaller the `radial_precision`, the better grid.
233+
234+
- For `min_num_angular_points` and `max_num_angular_points`, see “Angular
235+
grid” below.
236+
237+
- `alpha_max` is the steepest basis set exponent.
238+
239+
- `alpha_min` is a dictionary and holds the smallest exponents for each
240+
angular momentum (order does not matter).
241+
242+
- Using `center_index` we tell the code which of the atom centers is the one
243+
we have computed the grid for.
244+
245+
- `num_angular_grid_points` has to be one of the many supported Lebedev grids
246+
(see table on the bottom of this page).
247+
248+
249+
### Rust interface
250+
251+
Needs to be documented better but the library exposes functions with the same
252+
name as the Python interface and probably the best example on how it can be
253+
used are the [integration
254+
tests](https://github.com/dftlibs/numgrid/blob/main/tests/integration_test.rs).
255+
256+
257+
### Saving grid in NumPy format
258+
259+
The current API makes is relatively easy to export the computed grid in NumPy format.
260+
261+
In this example we save the angular grid coordinates and weights to two separate files
262+
in NumPy format:
263+
```python
264+
import numgrid
265+
import numpy as np
266+
267+
coordinates, weights = numgrid.angular_grid(14)
268+
269+
np.save("angular_grid_coordinates.npy", coordinates)
270+
np.save("angular_grid_weights.npy", weights)
271+
```
272+
273+
274+
## Parallelization
275+
276+
The Becke partitioning step is parallelized using
277+
[Rayon](https://github.com/rayon-rs/rayon). In other words, this step should
278+
be able to use all available cores on the computer or computing node. Since
279+
grids are currently generated atom by atom, it is also possible to parallelize
280+
"outside" by the caller.
281+
282+
283+
## Space partitioning
284+
285+
The molecular integration grid is generated from atom-centered grids by scaling
286+
the grid weights according to the Becke partitioning scheme, [JCP 88, 2547
287+
(1988)](http://dx.doi.org/10.1063/1.454033). The default Becke hardness is 3.
288+
289+
290+
## Radial grid
291+
292+
Two choices are available:
293+
- Lindh-Malmqvist-Gagliardi (https://dx.doi.org/10.1007/s002140100263)
294+
- Krack-Köster (https://doi.org/10.1063/1.475719)
295+
296+
Advantage of LMG scheme: The range of the radial grid is basis set dependent.
297+
The precision can be tuned with one single radial precision parameter. The
298+
smaller the radial precision, the better quality grid you obtain. The basis
299+
set (more precisely the Gaussian primitives/exponents) are used to generate the
300+
atomic radial grid range. This means that a more diffuse basis set generates a
301+
more diffuse radial grid.
302+
303+
Advantage of the KK scheme: parameter-free.
304+
305+
306+
## Angular grid
307+
308+
The angular grid is generated according to Lebedev and Laikov [A
309+
quadrature formula for the sphere of the 131st algebraic order of
310+
accuracy, Russian Academy of Sciences Doklady Mathematics, Volume 59,
311+
Number 3, 1999, pages 477-481].
312+
313+
The angular grid is pruned. The pruning is a primitive linear
314+
interpolation between the minimum number and the maximum number of
315+
angular points per radial shell. The maximum number is reached at 0.2
316+
times the Bragg radius of the center.
317+
318+
The higher the values for minimum and maximum number of angular points,
319+
the better.
320+
321+
For the minimum and maximum number of angular points the code will use
322+
the following table and select the closest number with at least the
323+
desired precision:
324+
```
325+
{6, 14, 26, 38, 50, 74, 86, 110, 146,
326+
170, 194, 230, 266, 302, 350, 434, 590, 770,
327+
974, 1202, 1454, 1730, 2030, 2354, 2702, 3074, 3470,
328+
3890, 4334, 4802, 5294, 5810}
329+
```
330+
331+
Taking the same number for the minimum and maximum number of angular
332+
points switches off pruning.

0 commit comments

Comments
 (0)