Auto-differentiation Tools#

The following are utility functions to compute some derivative quantities relevant to OFDFT. Examples of how to use them can be found here.

Functional Derivative#

functional_tools.get_functional_derivative(box_vecs, den, functional, requires_grad=False)#

Computes functional derivative

This is a utility function that computes the functional derivative

\[\frac{\delta F}{\delta n(\mathbf{r})}\]

of a given density functional \(F[n]\) via autograd. The functional derivative computed can be used for further derivatives if requires_grad = True.

Parameters:
  • box_vecs (torch.Tensor) – Lattice vectors

  • den (torch.Tensor) – Electron density

  • functional (function) – Density functional that takes in arguments box_vecs and den

  • requires_grad (bool) – Whether the fuctional derivative returned has requires_grad = True

Returns:

Functional derivative

Return type:

torch.Tensor

Linear Response#

functional_tools.get_inv_G(box_vecs, den, kinetic_functional, requires_grad=False)#

Computes linear response function

This is a utility function that computes the linear response function \(G^{-1}(\eta)\) where

\[G^{-1}(\eta) = \frac{\pi^2}{k_F} \left( \hat{\mathcal{F}} \left. \left\{ \frac{\delta^2 T_\text{S}}{\delta n(\mathbf{r}) \delta n(\mathbf{r}')} \right\} \right|_{n_0,n_0} \right)^{-1}\]

of a given density functional \(F[n]\) via autograd. The response function computed can be used for further derivatives if requires_grad = True. This utility function can be used for inspection purposes or even to fit the linear response of a kinetic functional to be closer to the Lindhard response, for example.

Parameters:
  • box_vecs (torch.Tensor) – Lattice vectors

  • den (torch.Tensor) – Electron density

  • kinetic_functional (function) – Kinetic functional that takes in arguments box_vecs and den

  • requires_grad (bool) – Whether the response function returned has requires_grad = True

Returns:

Linear response function

Return type:

torch.Tensor

Stress#

functional_tools.get_stress(box_vecs, den, functional, requires_grad=False)#

Computes stress

This is a utility function that computes the functional contribution to stress

\[\sigma_{ij} = \frac{1}{\Omega} \left.\frac{\partial F[n]}{\partial \epsilon_{ij}} \right|_{\epsilon_{ij} = 0} = \frac{1}{\Omega} \sum_k \frac{\partial F[n]}{\partial h_{ik}} h_{jk}\]

of a given density functional \(F[n]\) via autograd. \(h_{ij}\) are elements of a matrix whose columns are lattice vectors and the cell volume is \(\Omega\). The stress computed can be used for further derivatives if requires_grad = True.

Parameters:
  • box_vecs (torch.Tensor) – Lattice vectors

  • den (torch.Tensor) – Electron density

  • functional (function) – Density functional that takes in arguments box_vecs and den

  • requires_grad (bool) – Whether the response function returned has requires_grad = True

Returns:

Stress tensor (3 by 3)

Return type:

torch.Tensor

Pressure#

functional_tools.get_pressure(box_vecs, den, functional, requires_grad=False)#

Computes pressure

This is a utility function that computes the functional contribution to pressure

\[P_F = - \frac{dF[n]}{d\Omega}\]

of a given density functional \(F[n]\) via autograd, where \(\Omega\) is the volume of the cell. The pressure computed can be used for further derivatives if requires_grad = True.

Parameters:
  • box_vecs (torch.Tensor) – Lattice vectors

  • den (torch.Tensor) – Electron density

  • functional (function) – Density functional that takes in arguments box_vecs and den

  • requires_grad (bool) – Whether the response function returned has requires_grad = True

Returns:

Pressure

Return type:

torch.Tensor