[1]:
import qmctorch
INFO:QMCTorch| ____ __ ______________ _
INFO:QMCTorch| / __ \ / |/ / ___/_ __/__ ________/ /
INFO:QMCTorch|/ /_/ / / /|_/ / /__ / / / _ \/ __/ __/ _ \
INFO:QMCTorch|\___\_\/_/ /_/\___/ /_/ \___/_/ \__/_//_/
INFO:QMCTorch|
INFO:QMCTorch|0.4.0
Jastrow Factor
The wave function of the molecular system is written as :
where \(J(R)\) is the so called Jastrow factor, and \(A_\uparrow\)(\(A_\downarrow\)) is the matrix of the molecular orbitals values for the spin up(down) electron
The Jastrow factor is written as the exponential of a kernel function :
where \(r_{ij}\) denotes the distance between electrons \(i\) and \(j\). The kernel function \(f(r_{ij})\) can take differet forms. Traditionally it is written as a Pade-Jastrow function
where \(a\) is a fixed weight and \(\omega\) a variational parameter.
The electron-electron Jastrow factor class (JastrowFactorElectronElectron) orchestrates the calculations of the Jastrow factors (and its 1st and 2nd derivatives). It can take different kernel functions as for example the PadeJastrowKernel. The example below shows how to use this class.
In the simple Pade-Jastrow function the value of the \(a\) parameter is given by the so-called electron-electron cusp conditions. These conditions are here to insured that the value of the total energy remains finite at the coalescence point, i.e. when two electrons have the same positions.
It can be shown that this is respected when
for same-spin electrons and
for opposite spin electrons.
For the Pade-Jastrow function this translates into \(a=1/4\) (\(a=1/2\)) for same(opposite) spin electrons. However realizing the same condition for the fully connected Jastrow factor is still to be clarified.
[4]:
import torch
from qmctorch.scf import Molecule
from qmctorch.wavefunction.jastrows.elec_elec.jastrow_factor_electron_electron import JastrowFactorElectronElectron
from qmctorch.wavefunction.jastrows.elec_elec.kernels import PadeJastrowKernel
# create the molecule
mol = Molecule(atom='H 0. 0. 0; H 0. 0. 1.', calculator='pyscf', unit='bohr', redo_scf=True)
# define the jastrow factor
jastrow = JastrowFactorElectronElectron(
mol,
PadeJastrowKernel,
kernel_kwargs={'w': 0.1})
# define random electronic positions
nbatch = 10
pos = torch.rand(nbatch, mol.nelec * 3)
# compute the jastrow
jval = jastrow(pos)
INFO:QMCTorch|
INFO:QMCTorch| SCF Calculation
INFO:QMCTorch| Removing H2_pyscf_dzp.hdf5 and redo SCF calculations
INFO:QMCTorch| Running scf calculation
converged SCF energy = -1.07280585930373
INFO:QMCTorch| Molecule name : H2
INFO:QMCTorch| Number of electrons : 2
INFO:QMCTorch| SCF calculator : pyscf
INFO:QMCTorch| Basis set : dzp
INFO:QMCTorch| SCF : HF
INFO:QMCTorch| Number of AOs : 10
INFO:QMCTorch| Number of MOs : 10
INFO:QMCTorch| SCF Energy : -1.073 Hartree
Neural Jastrows
The functional form \(f(r_{ij}) = ar_{ij}(1+\omega r_{ij})^{-1}\) only offers one single variational parameter and does not offer a lot of flexibility. It is however possible to replace that form by a simple fully connected neural network
This network takes a single input value (\(r_{ij}\)) and outputs a single value, i.e. the value of the kernel. A simple 2 layer fully connected neurakl network Jastrow Kernel has been implemented in the FullyConnectedJastrowKernel class that can be used in the JastrowFactorElectronElectron as follow:
[5]:
import torch
from qmctorch.scf import Molecule
from qmctorch.wavefunction.jastrows.elec_elec.jastrow_factor_electron_electron import JastrowFactorElectronElectron
from qmctorch.wavefunction.jastrows.elec_elec.kernels import FullyConnectedJastrowKernel
# number of spin up/down electrons
mol = Molecule(atom='H 0. 0. 0; H 0. 0. 1.', calculator='pyscf', unit='bohr', redo_scf=True)
# define the jastrow factor
jastrow = JastrowFactorElectronElectron(
mol,
FullyConnectedJastrowKernel,
kernel_kwargs={'size1': 32, 'size2': 64})
# define random electronic positions
nbatch = 10
pos = torch.rand(nbatch, mol.nelec * 3)
# compute the jastrow
jval = jastrow(pos)
INFO:QMCTorch|
INFO:QMCTorch| SCF Calculation
INFO:QMCTorch| Removing H2_pyscf_dzp.hdf5 and redo SCF calculations
INFO:QMCTorch| Running scf calculation
converged SCF energy = -1.07280585930373
INFO:QMCTorch| Molecule name : H2
INFO:QMCTorch| Number of electrons : 2
INFO:QMCTorch| SCF calculator : pyscf
INFO:QMCTorch| Basis set : dzp
INFO:QMCTorch| SCF : HF
INFO:QMCTorch| Number of AOs : 10
INFO:QMCTorch| Number of MOs : 10
INFO:QMCTorch| SCF Energy : -1.073 Hartree
SlaterJastrow Wave function
Both Jastrow factors can be used to define a SlaterJastrow wavefunction. The example below shows how to do that for a LiH molecule
[7]:
import torch
from qmctorch.scf import Molecule
from qmctorch.wavefunction import SlaterJastrow
from qmctorch.wavefunction.jastrows.elec_elec.kernels import PadeJastrowKernel, FullyConnectedJastrowKernel
# define the molecule
mol = Molecule(
atom='Li 0 0 0; H 0 0 3.14',
unit='bohr',
calculator='pyscf',
basis='sto-3g')
# define the jastrow factor
jastrow = JastrowFactorElectronElectron(
mol,
FullyConnectedJastrowKernel,
kernel_kwargs={'size1': 32, 'size2': 64})
# define the Slater Jastrow wavefunction
wf = SlaterJastrow(mol,
jastrow=jastrow,
configs='single_double(2,2)')
# define random electronic positions
nbatch = 10
pos = torch.rand(nbatch, mol.nelec * 3)
# compute the value of the wave function
wfval = wf(pos)
INFO:QMCTorch|
INFO:QMCTorch| SCF Calculation
INFO:QMCTorch| Reusing scf results from LiH_pyscf_sto-3g.hdf5
INFO:QMCTorch|
INFO:QMCTorch| Wave Function
INFO:QMCTorch| Backflow : False
INFO:QMCTorch| Jastrow factor : True
INFO:QMCTorch| Jastrow kernel : ee -> FullyConnectedJastrowKernel
INFO:QMCTorch| Highest MO included : 6
INFO:QMCTorch| Configurations : single_double(2,2)
INFO:QMCTorch| Number of confs : 4
INFO:QMCTorch| Kinetic energy : jacobi
INFO:QMCTorch| Number var param : 2210
INFO:QMCTorch| Cuda support : False