|
| 1 | +.. _pbc_dft_multigrid: |
| 2 | + |
| 3 | +pbc.dft.multigrid --- Multigrid Integration |
| 4 | +******************************************* |
| 5 | + |
| 6 | +Multigrid is a numerical integration algorithm optimized for the computation of |
| 7 | +the Coulomb matrix and exchange-correlation (XC) functional. It can take |
| 8 | +advantage of the locality of density and orbitals when computing electron |
| 9 | +density and matrix elements. |
| 10 | + |
| 11 | +The Multigrid algorithm employs different integration grids for different types |
| 12 | +of orbitals. Diffuse orbitals use sparse integration grids, while compact |
| 13 | +orbitals utilize denser grids. The calculations for compact orbitals are only |
| 14 | +performed within smaller spatial regions. The numerical values from different |
| 15 | +grids are then aggregated in reciprocal space using the fast Fourier transform. |
| 16 | + |
| 17 | +Compared to the `get_j` function provided by the FFTDF module and the XC matrix |
| 18 | +evaluation functions offered by the `numint` module, the Multigrid algorithm |
| 19 | +can achieve an order of magnitude improvement in the computation of the Coulomb |
| 20 | +matrix and DFT XC matrix. |
| 21 | + |
| 22 | +Supported Features |
| 23 | +================== |
| 24 | + |
| 25 | +The Multigrid algorithm is designed to accelerate DFT calculations. |
| 26 | +It can also be utilized to speed up derived properties based on DFT, such as |
| 27 | +TDDFT excited state calculations, stability analysis, analytical nuclear |
| 28 | +gradients, and the computation of the orbital Hessian in second-order SCF |
| 29 | +(SOSCF) methods. However, it does not support the computation of the HF exchange |
| 30 | +matrix or the calculation of MO two-electron integrals in post-HF methods. |
| 31 | + |
| 32 | +In terms of supported systems, the Multigrid algorithm can be applied to both |
| 33 | +periodic systems and molecular calculations. For periodic systems, it supports |
| 34 | +single k-point calculations as well as k-point sampling in DFT calculations. For |
| 35 | +molecular systems, additional configurations are required to enable the multigrid |
| 36 | +algorithm, see :ref:`mole_multigrid`. |
| 37 | + |
| 38 | +Generally, the Multigrid algorithm should be used with pseudopotentials and the |
| 39 | +corresponding basis sets to reduce computational costs and accuracy. |
| 40 | +Using the Multigrid algorithm for all-electron calculations typically results in significant overhead. |
| 41 | + |
| 42 | + |
| 43 | +How to enable MultiGrid algorithm |
| 44 | +================================= |
| 45 | + |
| 46 | +In periodic system calculations, enabling the Multigrid algorithm is |
| 47 | +straightforward. The PBC SCF class provides a method `multigrid_numint()`. |
| 48 | +This method creates a new SCF instance which is configured with the Multigrid |
| 49 | +functionality. This new instance can then be used in the same way as a standard |
| 50 | +SCF instance. For example:: |
| 51 | + |
| 52 | + cell = pyscf.M( |
| 53 | + a = np.eye(3)*3.5668, |
| 54 | + atom = '''C 0. 0. 0. |
| 55 | + C 0.8917 0.8917 0.8917 |
| 56 | + C 1.7834 1.7834 0. |
| 57 | + C 2.6751 2.6751 0.8917 |
| 58 | + C 1.7834 0. 1.7834 |
| 59 | + C 2.6751 0.8917 2.6751 |
| 60 | + C 0. 1.7834 1.7834 |
| 61 | + C 0.8917 2.6751 2.6751''', |
| 62 | + basis = 'gth-dzv', |
| 63 | + pseudo = 'gth-pade', |
| 64 | + ) |
| 65 | + mf = cell.KRKS(xc='pbe', kpts=cell.make_kpts([3,3,3])) |
| 66 | + mf = mf.multigrid_numint() |
| 67 | + mf.run() |
| 68 | + |
| 69 | +Once the Multigrid algorithm is enabled, it is automatically applied to other |
| 70 | +methods based on that SCF instance, such as TDDFT and SOSCF. For example:: |
| 71 | + |
| 72 | + mf = cell.KRKS(xc='pbe', kpts=cell.make_kpts([3,3,3])) |
| 73 | + mf = mf.multigrid_numint() |
| 74 | + |
| 75 | + mf = mf.soscf().run() |
| 76 | + |
| 77 | + mf.TDA().run() |
| 78 | + |
| 79 | + mf.Gradients().run() |
| 80 | + |
| 81 | +The Multigrid algorithm is enabled through the `._numint` attribute of the SCF |
| 82 | +instance You can directly modify the `._numint` attribute of an SCF instance to |
| 83 | +apply the Multigrid algorithm.:: |
| 84 | + |
| 85 | + from pyscf.pbc.dft.numint import MultiGridNumInt |
| 86 | + mf = cell.KRKS(xc='pbe', kpts=cell.make_kpts([3, 3, 3])) |
| 87 | + mf._numint = MultiGridNumInt(cell) |
| 88 | + mf.run() |
| 89 | + |
| 90 | +Configurable Options |
| 91 | +==================== |
| 92 | + |
| 93 | +In most scenarios, the Multigrid module can automatically configure parameters such |
| 94 | +as energy cutoff, radius cutoff, sub tasks to balance computational load and |
| 95 | +accuracy. If you need more precise control over the Multigrid algorithm, |
| 96 | +you can modify the attributes of the `mf._numint`. Here are some configurable options. |
| 97 | + |
| 98 | +* `mesh`: It's a 3-element tuple, which controls the upper limit of the mesh |
| 99 | + points utilized by the algorithm. By default, this value is estimated based on |
| 100 | + the basis set, the shape, and the size of the lattice. By default, the error in |
| 101 | + the electron density at each mesh point is controlled to be below `cell.precision`. |
| 102 | + |
| 103 | +* `ntasks`: The maximum number of subgroups. The Multigrid algorithm divides |
| 104 | + orbital pairs into subgroups and processes the integration for each subgroup |
| 105 | + separately. Increasing the number of tasks can better utilize the locality of |
| 106 | + the orbital functions, reducing the number of floating-point operations |
| 107 | + (FLOPS). However, it can also increase the overhead of other operations, such |
| 108 | + as FFT. The recommended value for `ntasks` is typically set between 3 and 6. |
| 109 | + The default value is 4. |
| 110 | + |
| 111 | +* `xc_with_j`: Determines whether the calculation of the XC matrix should also |
| 112 | + include the calculation of the Coulomb energy and the Coulomb matrix. |
| 113 | + Combining the calculation of the XC and Coulomb can reduce the computation cost. |
| 114 | + For GGA functionals, it can reduce the computational load by 30% - 40%. |
| 115 | + The default setting is `True`, and it is generally recommended to enable this option. |
| 116 | + |
| 117 | +* `ke_ratio`: Controls the ratio of the energy cutoffs among the different |
| 118 | + subtasks when partitioning the orbital pairs. `ke_ratio` is a number greater |
| 119 | + than 1. When approaching 1, the task partitioning is fine, and the orbital |
| 120 | + locality is better utilized. However, this also increases the number of tasks. |
| 121 | + Regardless of the configuration of this parameter, the maximum number of tasks |
| 122 | + generated is still controlled by the `ntasks` attribute. |
| 123 | + |
| 124 | + |
| 125 | +Compatibility with NumInt |
| 126 | +========================= |
| 127 | + |
| 128 | +The `NumInt` class offers numerical integration functions for DFT calculations. |
| 129 | +It is assigned to the `_numint` attribute of SCF classes. This module offers |
| 130 | +APIs such as `get_rho` (for computing electron density in real space) and |
| 131 | +`get_vxc` (for computing the value of the XC energy functional and XC matrices), |
| 132 | +for DFT calculations :ref:`dft`. Both molecular and PBC DFT implementations |
| 133 | +follow this API design. |
| 134 | + |
| 135 | +The `pyscf.pbc.dft.multigrid` module offers the `MultiGridNumInt` class, which |
| 136 | +is compatible with the `NumInt` class. Its methods, such as `get_vxc`, `get_fxc`, |
| 137 | +`get_rho`, `cache_xc_kernel`, `nr_rks`, and `nr_uks`, are mostly compatible |
| 138 | +with the corresponding methods in NumInt (with only a few additional keyword |
| 139 | +arguments for controlling multigrid instances). These methods can be |
| 140 | +individually invoked, like those in the `NumInt` class, to compute densities and |
| 141 | +XC matrix elements. |
| 142 | + |
| 143 | +The `pyscf.pbc.dft.multigrid` module also provides the `MultiGridNumInt2` class, |
| 144 | +which further optimizes the implementations of the `MultiGridNumInt` class. |
| 145 | +However, due to differences in the algorithm implementations, the support for |
| 146 | +optimized k-points and non-orthogonal lattices is not as comprehensive as that |
| 147 | +in the `MultiGridNumInt` class. Currently, the `SCF.multigrid_numint()` method |
| 148 | +invokes the `MultiGridNumInt` class. To maximize the multigrid performance, you |
| 149 | +can manually assign the `MultiGridNumInt2` instance to the `mf._numint` |
| 150 | +attribute. |
| 151 | + |
| 152 | +The two classes will be merged into one in the future release. |
| 153 | + |
| 154 | + |
| 155 | +.. _mole_multgird: |
| 156 | + |
| 157 | +How to Apply Multigrid in Molecular DFT |
| 158 | +======================================= |
| 159 | + |
| 160 | +The Multigrid algorithm is currently designed and implemented for data |
| 161 | +structures with periodic boundary conditions. Nevertheless, it can be adapted |
| 162 | +for molecular calculations. |
| 163 | + |
| 164 | +First, we need to initialize molecule within a relatively large periodic lattice. |
| 165 | +A vacuum space needs to be placed between the box and the molecule to |
| 166 | +simulate free boundary conditions:: |
| 167 | + |
| 168 | + cell = pyscf.M(atom=''' |
| 169 | + O 0.000 0.118 0. |
| 170 | + H 0.758 -0.470 0. |
| 171 | + H -0.758 -0.470 0.''', |
| 172 | + a=np.eye(3)*10, |
| 173 | + dimension=0, |
| 174 | + basis='gth-dzvp', pseudo='gth-pade',) |
| 175 | + |
| 176 | +Here, we apply a 10 x 10 x 10 (unit Angstrom) box. The box does not need to be |
| 177 | +excessively large. It only needs to ensure that the electron density of the molecule |
| 178 | +does not leak outside the box. If there are no diffused functions, typically, a |
| 179 | +5 Angstrom margin around the molecule is sufficient. The lattice is a virtual |
| 180 | +box which does not need to be centered on the origin. There is no need to adjust |
| 181 | +the molecule's coordinates to the center of the box. |
| 182 | + |
| 183 | +Alternatively, the lattice can be automatically determined. We can just create a |
| 184 | +`Mole` instance and then call the `Mole.to_cell()` method to convert a `Mole` |
| 185 | +object into a Cell object:: |
| 186 | + |
| 187 | + mol = pyscf.M(atom=''' |
| 188 | + O 0.000 0.118 0. |
| 189 | + H 0.758 -0.470 0. |
| 190 | + H -0.758 -0.470 0.''', |
| 191 | + basis='gth-dzvp', pseudo='gth-pade') |
| 192 | + cell = mol.to_cell(dimension=0) |
| 193 | + |
| 194 | +When initializing the Cell, we set `dimension=0`. This setting informs the |
| 195 | +program that the system is a 0-dimensional system (molecule), which allows the |
| 196 | +program to more effectively utilize this property to truncate the long-range |
| 197 | +Coulomb potential and accelerate the computation of certain integrals. |
| 198 | +The system can also be treated as a 3-dimensional crystal, with slightly |
| 199 | +increased computational load. |
| 200 | + |
| 201 | +In this system, we use the GTH pseudo potential and the GTH basis set. This |
| 202 | +basis set does not have very steep GTO functions, making it suitable for the |
| 203 | +multigrid method. |
| 204 | + |
| 205 | +With this `Cell` object, we can initialize the DFT instance as we would for |
| 206 | +typical PBC DFT calculations. The following example demonstrates another |
| 207 | +way which integrates |
| 208 | +the Multigrid XC matrix functionality into the the molecular DFT instances.:: |
| 209 | + |
| 210 | + from pyscf.pbc.dft.multigrid import MultiGridNumInt2 |
| 211 | + mol = pyscf.M(atom=''' |
| 212 | + O 0.000 0.118 0. |
| 213 | + H 0.758 -0.470 0. |
| 214 | + H -0.758 -0.470 0.''', |
| 215 | + basis='gth-dzvp', pseudo='gth-pade') |
| 216 | + mf = mol.RKS(xc='pbe') |
| 217 | + |
| 218 | + cell = mol.to_cell(dimension=0) |
| 219 | + mf._numint = MultiGridNumInt2(cell) |
| 220 | + mf._numint.xc_with_j = False |
| 221 | + |
| 222 | + mf.run() |
| 223 | + |
| 224 | +In this example, we use the `MultiGridNumInt` class for `mf._numint` of the |
| 225 | +molecular DFT instance. This setup invokes the `MultiGridNumInt` algorithm to |
| 226 | +calculate the DFT XC matrix and XC energy, while calls the standard molecular |
| 227 | +`get_jk` functions for Coulomb energy. |
| 228 | +Note the setting `xc_with_j=False`, which disables the computation of Coulomb |
| 229 | +energy by the `MultiGridNumInt` class. This is necessary because the molecular |
| 230 | +DFT program employs a different method to compute nuclear repulsion energy |
| 231 | +compared to the method used in PBC DFT. |
| 232 | +When using the molecular DFT program in conjunction with `MultiGridNumInt`, we |
| 233 | +should not use `MultiGridNumInt` to compute the Coulomb energy. |
| 234 | + |
| 235 | + |
| 236 | +Limitations of Multigrid algorithm |
| 237 | +================================== |
| 238 | + |
| 239 | +* The Multigrid algorithm only supports uniform grids. Currently, it cannot be used with Becke grids. |
| 240 | + |
| 241 | +* The `MultiGridNumInt` class does not support the calculation of analytical nuclear gradients. |
| 242 | + |
| 243 | +* The `MultiGridNumInt2` class does not support k-point |
| 244 | + calculations, meta-GGA functionals, or the computation of the TDDFT fxc kernel. |
| 245 | + |
| 246 | + |
| 247 | +Examples |
| 248 | +======== |
| 249 | +* :source:`examples/pbc/27-multigrid.py` |
| 250 | +* :source:`examples/pbc/27-multigrid2.py` |
0 commit comments