02SiO2 at k = Gamma

00 Introduction

From this tutorial, you can learn how to calculate SiO2 (at k=gamma) with JDFT ansatz starting from a pySCF calculation by turbo-genius. You can download all the input and output files from here.

01 PySCF calculation and its conversion to a TREXIO file

Run a PySCF calculation.

Note

You can skip this step!! since this is a litte heavy calculation.

# pyscf calculation
cd 00pyscf_to_trexio
python pyscf_SiO2.py

The Python code is:

#!/usr/bin/env python
# coding: utf-8

# pySCF -> pyscf checkpoint file (SiO2 with single-k)

# load python packages
import os, sys
import numpy as np

# load ASE modules
from ase.io import read

# load pyscf packages
from pyscf import gto, scf, mp, tools
from pyscf.pbc import gto as gto_pbc
from pyscf.pbc import dft as pbcdft
from pyscf.pbc import scf as pbcscf

#open boundary condition
structure_file="1011097.cif"
checkpoint_file="SiO2.chk"
pyscf_output="out_SiO2_pyscf"
charge=0
spin=0
basis={
# basis set optimized for solids:
# Correlation-Consistent Gaussian Basis Sets for Solids Made Simple, H.-Z. Ye and T. C. Berkelbach, J. Chem. Theory Comput., 18, 1595--1606 (2022). doi: 10.1021/acs.jctc.1c01245
'Si': gto.basis.parse("""
    #BASIS SET: (5s,4p,2d,1f) -> [3s,3p,2d,1f] Si
    Si  S
    2.741335    4.650395e-02
    1.405628   -3.054975e-01
    0.273354    4.969654e-01
    Si  S
    0.123202    1.000000e+00
    Si  S
    0.055965    1.000000e+00
    Si  P
    1.616545   -3.536164e-02
    0.382436    3.057198e-01
    Si  P
    0.147904    1.000000e+00
    Si  P
    0.055817    1.000000e+00
    Si  D
    0.534081    1.000000e+00
    Si  D
    0.170283    1.000000e+00
    Si  F
    0.347183    1.000000e+00
"""),
'O': gto.basis.parse("""
    #BASIS SET: (7s,7p,2d,1f) -> [3s,3p,2d,1f] O
    O  S
    19.617729    1.415845e-02
    7.154197   -1.740638e-01
    1.137108    3.984802e-01
    0.456668    5.352995e-01
    0.182222    1.954256e-01
    O  S
    2.023130    1.000000e+00
    O  S
    0.267780    1.000000e+00
    O  P
    14.664866    3.867801e-02
    4.563435    1.586589e-01
    1.549011    3.591587e-01
    0.531230    4.522952e-01
    0.173419    2.457321e-01
    O  P
    0.657437    1.000000e+00
    O  P
    0.211337    1.000000e+00
    O  D
    2.353379    1.000000e+00
    O  D
    0.656002    1.000000e+00
    O  F
    1.460952    1.000000e+00
""")
}
ecp='ccecp'
scf_method="DFT"  # HF or DFT
dft_xc="LDA_X,LDA_C_PZ" # XC for DFT
exp_to_discard = 0.00
twist_average = False
kpt = [0, 0, 0]
kpt_grid = [1, 1, 1]

print(f"structure file = {structure_file}")
atom=read(structure_file)

# construct a cell
cell=gto_pbc.M()
cell.from_ase(atom)
cell.verbose = 5
cell.output = pyscf_output
cell.charge = charge
cell.spin = spin
cell.symmetry = False
a=cell.a
cell.a=np.array([a[0], a[1], a[2]]) # otherwise, we cannot dump a

# basis set
cell.basis = basis
cell.exp_to_discard=exp_to_discard

# define ecp
cell.ecp = ecp

cell.build(cart=False)

# calc type setting
print(f"scf_method = {scf_method}")  # HF/DFT

if scf_method == "HF":
    # HF calculation
    if cell.spin == 0:
        print("HF kernel=RHF")
        if twist_average:
            print("twist_average=True")
            kpt_grid_m = cell.make_kpts(kpt_grid)
            mf = pbcscf.khf.KRHF(cell, kpt_grid_m)
            mf = mf.newton()
        else:
            print("twist_average=False")
            mf = pbcscf.hf.RHF(cell, kpt=cell.get_abs_kpts(scaled_kpts=[kpt])[0])
            mf = mf.newton()

    else:
        print("HF kernel=ROHF")
        if twist_average:
            print("twist_average=True")
            kpt_grid_m = cell.make_kpts(kpt_grid)
            mf = pbcscf.krohf.KROHF(cell, kpt_grid_m)
            mf = mf.newton()
        else:
            print("twist_average=False")
            mf = pbcscf.rohf.ROHF(cell, kpt=cell.get_abs_kpts(scaled_kpts=[kpt])[0])
            mf = mf.newton()

    mf.chkfile = checkpoint_file

elif scf_method == "DFT":
    # DFT calculation
    if cell.spin == 0:
        print("DFT kernel=RKS")
        if twist_average:
            print("twist_average=True")
            kpt_grid_m = cell.make_kpts(kpt_grid)
            mf = pbcdft.krks.KRKS(cell, kpt_grid_m)
            mf = mf.newton()
            #print(dir(mf))
            #sys.exit()
        else:
            print("twist_average=False")
            mf = pbcdft.rks.RKS(cell, kpt=cell.get_abs_kpts(scaled_kpts=[kpt])[0])
            mf = mf.newton()
    else:
        print("DFT kernel=ROKS")
        if twist_average:
            print("twist_average=True")
            kpt_grid_m = cell.make_kpts(kpt_grid)
            mf = pbcdft.kroks.KROKS(cell, kpt_grid_m)
            mf = mf.newton()
        else:
            print("twist_average=False")
            mf = pbcdft.roks.ROKS(cell, kpt=cell.get_abs_kpts(scaled_kpts=[kpt])[0])
            mf = mf.newton()

    mf.chkfile = checkpoint_file
    mf.xc = dft_xc
else:
    raise NotImplementedError

total_energy = mf.kernel()

# HF/DFT energy
print(f"Total HF/DFT energy = {total_energy}")
print("HF/DFT calculation is done.")
print("PySCF calculation is done.")
print(f"checkpoint file = {checkpoint_file}")

You can convert the generated PySCF checkpoint file to a TREXIO file

# pyscf chkfile to TREXIO
trexio convert-from -t pyscf -i SiO2.chk -b hdf5 SiO2.hdf5

02 From TREXIO file to TurboRVB WF

cd ../01trexio_to_turborvbwf/
cp ../00pyscf_to_trexio/SiO2.hdf5 .

trexio-to-turborvb SiO2.hdf5 -jasbasis cc-pVDZ -jascutbasis

Note

If you want to specify Jastrow basis set, you can use the following python script to convert the TREXIO file.

cd ../01trexio_to_turborvbwf/
cp ../00pyscf_to_trexio/SiO2.hdf5 .
vi trexio_turborvb_wf_converter.py # define your Jastrow basis
python trexio_turborvb_wf_converter.py

The Python code is:

#!/usr/bin/env python
# coding: utf-8

# load python packages
import os, sys

# load turbogenius module
from turbogenius.trexio_to_turborvb import trexio_to_turborvb_wf
from turbogenius.trexio_wrapper import Trexio_wrapper_r
from turbogenius.pyturbo.basis_set import Jas_Basis_sets

# TREXIO file
trexio_file="SiO2.hdf5"

# Jastrow basis (GAMESS format)
jastrow_basis_dict={
    'Si':"""
        S  1
        1  28.560000  1.000000
        S  1
        1  10.210000  1.000000
        S  1
        1   3.838000  1.000000
        S  1
        1   0.746600  1.000000
        P  1
        1  13.550000  1.000000
        P  1
        1   2.917000  1.000000
        P  1
        1   0.797300  1.000000
    """,
    'O':"""
        S  1
        1  1.9620000  1.000000
        S  1
        1  0.4446000  1.000000
        S  1
        1  0.1220000  1.000000
        P  1
        1  0.7270000  1.000000
    """
}

# Generage jastrow basis set list
trexio_r = Trexio_wrapper_r(
    trexio_file=trexio_file
)
jastrow_basis_list = [
    jastrow_basis_dict[element]
    for element in trexio_r.labels_r
]
jas_basis_sets = (
    Jas_Basis_sets.parse_basis_sets_from_texts(
        jastrow_basis_list, format="gamess"
    )
)

# Convert the TREXIO file to TurboRVB WF.
trexio_to_turborvb_wf(
    trexio_file=trexio_file,
    jas_basis_sets=jas_basis_sets,
    only_mol=True,
)

03 JDFT ansatz - Jastrow optimization

One should refer to the Hydrogen tutorial for the details. Here, only needed commands are shown.

cd ../02optimization/
cp ../01trexio_to_turborvbwf/fort.10 fort.10
cp ../01trexio_to_turborvbwf/pseudo.dat ./
cp fort.10 fort.10_pyscf
turbogenius vmcopt -g -opt_onebody -opt_twobody -opt_jas_mat -optimizer lr -vmcoptsteps 300 -steps 100

# on a local machine (serial version)
turborvb-serial.x < datasmin.input > out_min
# on a local machine (parallel version)
mpirun -np XX turborvb-mpi.x < datasmin.input > out_min
# on a cluster machine (PBS)
qsub submit.sh
# on a cluster machine (Slurm)
sbatch submit.sh

turbogenius vmcopt -post -optwarmup 280 -plot

04 JDFT ansatz - VMC

cd ../03vmc/
cp ../02optimization/fort.10 fort.10
cp ../02optimization/pseudo.dat .
turbogenius vmc -g -steps 500

# on a local machine (serial version)
turborvb-serial.x < datasvmc.input > out_vmc
# on a local machine (parallel version)
mpirun -np XX turborvb-mpi.x < datasvmc.input > out_vmc
# on a cluster machine (PBS)
qsub submit.sh
# on a cluster machine (Slurm)
sbatch submit.sh

turbogenius vmc -post -bin 10 -warmup 5