Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add sofk estimator test and manual entry about how estimator works #764

Merged
merged 8 commits into from
Dec 18, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions manual/backflow_implementation.tex
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
\newcommand{\bs}{\boldsymbol}
\newcommand{\tr}{\text{tr}}
\section{Slater-Backflow Wavefunction Implementation Details}

For simplicity, consider $N$ identical fermions of the same spin (e.g. up electrons) at spatial locations $\{\bs{r}_1,\bs{r}_2,\dots,\bs{r}_{N}\}$. Then the Slater determinant can be written as
Expand Down
1 change: 1 addition & 0 deletions manual/developing.tex
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ \chapter{Development Guide}
\input{coding_standards}

\input{estimator_implementation}
\input{estimator_manager}
\input{backflow_implementation}
298 changes: 298 additions & 0 deletions manual/estimator_manager.tex

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions manual/qmcpack_manual.tex
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,8 @@
\newcommand{\overlap}[2]{\langle #1 \lvert #2 \rangle}
\newcommand{\operator}[3]{\ket{#1} #2 \bra{#3}}
\newcommand{\idop}{\hat{\mathbb{1}}}
\newcommand{\bs}{\boldsymbol}
\newcommand{\tr}{\text{tr}} % trace


\begin{document}
Expand Down
30 changes: 30 additions & 0 deletions tests/estimator/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,33 @@ if (add_test)
latdev_check.py
)
endif()

set(sofk_python_reqs numpy;pandas;h5py)
CHECK_PYTHON_REQS(sofk_python_reqs estimator-sofk add_test)

if (add_test)
SIMPLE_RUN_AND_CHECK(estimator-sofk_pbyp-properties
"${CMAKE_SOURCE_DIR}/tests/estimator/sofk"
pbyp_dat-h5.xml
1 16
check_properties_h5dat.py dat-h5_pbyp
)
SIMPLE_RUN_AND_CHECK(estimator-sofk_pbyp-collectables
"${CMAKE_SOURCE_DIR}/tests/estimator/sofk"
pbyp_dat-h5.xml
1 16
check_collectables_h5dat.py dat-h5_pbyp
)
SIMPLE_RUN_AND_CHECK(estimator-sofk_allp-properties
"${CMAKE_SOURCE_DIR}/tests/estimator/sofk"
allp_dat-h5.xml
1 16
check_properties_h5dat.py dat-h5_allp
)
SIMPLE_RUN_AND_CHECK(estimator-sofk_allp-collectables
"${CMAKE_SOURCE_DIR}/tests/estimator/sofk"
allp_dat-h5.xml
1 16
check_collectables_h5dat.py dat-h5_allp
)
endif()
91 changes: 91 additions & 0 deletions tests/estimator/sofk/allp_dat-h5.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<?xml version="1.0"?>
<simulation>
<project id="dat-h5_allp" series="0">
<application name="qmcapp" role="molecu" class="serial" version="1.0"/>
</project>
<qmcsystem>
<simulationcell>
<parameter name="lattice" units="bohr">
3.77945227 0.00000000 0.00000000
-0.00000000 3.77945227 0.00000000
-0.00000000 -0.00000000 3.77945227
</parameter>
<parameter name="bconds">
p p p
</parameter>
<parameter name="LR_dim_cutoff" > 15 </parameter>
</simulationcell>
<particleset name="e" random="yes">
<group name="u" size="1" mass="1.0">
<parameter name="charge" > -1 </parameter>
<parameter name="mass" > 1.0 </parameter>
</group>
<group name="d" size="1" mass="1.0">
<parameter name="charge" > -1 </parameter>
<parameter name="mass" > 1.0 </parameter>
</group>
</particleset>
<particleset name="ion0">
<group name="H" size="2" mass="1837.36221934">
<parameter name="charge" > 1 </parameter>
<parameter name="valence" > 1 </parameter>
<parameter name="atomicnumber" > 1 </parameter>
<parameter name="mass" > 1837.36221934 </parameter>
<attrib name="position" datatype="posArray" condition="0">
0.00000000 0.00000000 0.00000000
1.88972614 1.88972614 1.88972614
</attrib>
</group>
</particleset>
<wavefunction name="psi0" target="e">
<determinantset type="einspline" href="pwscf.pwscf.h5" tilematrix="1 0 0 0 1 0 0 0 1" twistnum="0" source="ion0" meshfactor="1.0" precision="float">
<slaterdeterminant>
<determinant id="updet" size="1">
<occupation mode="ground" spindataset="0"/>
</determinant>
<determinant id="downdet" size="1">
<occupation mode="ground" spindataset="0"/>
</determinant>
</slaterdeterminant>
</determinantset>
<jastrow type="One-Body" name="J1" function="bspline" source="ion0" print="yes">
<correlation elementType="H" size="8" cusp="1.0">
<coefficients id="eH" type="Array">
0.00206602038 -0.002841926986 0.0036266191 -0.001913930279 8.457152991e-06
0.0007380321824 3.635172529e-05 0.0001299635851
</coefficients>
</correlation>
</jastrow>
<jastrow type="Two-Body" name="J2" function="bspline" print="yes">
<correlation speciesA="u" speciesB="d" size="8">
<coefficients id="ud" type="Array">
0.5954603818 0.5062051797 0.3746940461 0.2521010502 0.1440163317 0.07796688253
0.03804420551 0.01449320872
</coefficients>
</correlation>
</jastrow>
</wavefunction>
<hamiltonian name="h0" type="generic" target="e">
<pairpot type="coulomb" name="ElecElec" source="e" target="e"/>
<pairpot type="coulomb" name="IonIon" source="ion0" target="ion0"/>
<pairpot type="coulomb" name="ElecIon" source="ion0" target="e"/>
<estimator type="sk" name="sk" hdf5="no"/>
<estimator type="sk" name="h5sk" hdf5="yes"/>
</hamiltonian>
</qmcsystem>
<qmc method="vmc" move="byp">
<parameter name="walkers" > 64 </parameter>
<parameter name="blocks" > 16 </parameter>
<parameter name="steps" > 2 </parameter>
<parameter name="subSteps" > 2 </parameter>
<parameter name="timestep" > 2.0 </parameter>
<parameter name="warmupSteps" > 16 </parameter>
</qmc>
<qmc method="dmc" move="byp">
<parameter name="targetwalkers" > 64 </parameter>
<parameter name="blocks" > 16 </parameter>
<parameter name="steps" > 1 </parameter>
<parameter name="timestep" > 2.0 </parameter>
<parameter name="warmupSteps" > 0 </parameter>
</qmc>
</simulation>
92 changes: 92 additions & 0 deletions tests/estimator/sofk/check_collectables_h5dat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#!/usr/bin/env python
import sys
import os
import h5py
import numpy as np
from check_properties_h5dat import read


def get_last_sk(fdat,fh5):
""" extract S(k) at the longest k vector from scalar.dat and stat.h5

Args:
fdat (str): name of scalar.dat file
fh5 (str): name of stat.h5 file
Return:
tuple: (myy, h5y), S(k_max) at each block from scalar.dat and stat.h5
"""

# get S(k) from scalar.dat
df = read(fdat)
sk_cols = [col for col in df.columns if col.startswith('sk')]
myy = df[sk_cols[-1]].values

# get S(k) from stat.h5
fp = h5py.File(fh5, 'r')
h5y = fp['h5sk/value'].value.T[-1]
fp.close()

return myy, h5y
# end def


def show_scalar_trace(data, seriesl):
import matplotlib.pyplot as plt
method_map = {0:'VMC',1:'DMC'}
fig,ax_arr = plt.subplots(1, 2, sharey=True)
ax_arr[0].set_ylabel('S(k->inf)')
iplot = 0
for iseries in seriesl:
ax = ax_arr[iplot]
ax.set_title(method_map[iseries])
ax.set_xlabel('block')
ax.set_ylim(0.3, 1.2)

entry = data[iseries]
daty = entry['daty']
h5y = entry['h5y']

sline = ax.plot(daty)
hline = ax.plot(h5y, ls='--', lw=2, alpha=0.8)

ax.legend(
handles = [sline[0], hline[0]]
,labels = ['scalar.dat', 'stat.h5']
,loc=0
)

iplot += 1
# end for iseries
plt.show()


if __name__ == '__main__':

prefix = sys.argv[1]
seriesl= [0,1] # a list of series IDs to check

# check Properties v.s. Collectables
collectable_success_map = {}
data = {}
for iseries in seriesl:

# define files to read
fdat = '%s.s00%d.scalar.dat' % (prefix, iseries)
fh5 = '%s.s00%d.stat.h5' % (prefix, iseries)

daty, h5y = get_last_sk(fdat, fh5)
success = np.allclose(daty, h5y, atol=0.1)
collectable_success_map[iseries] = success

# save data for plotting
data[iseries] = {'daty':daty, 'h5y':h5y}
# end for
all_success = np.all( collectable_success_map.values() )

if all_success:
sys.exit(0)
else:
#show_scalar_trace(data, seriesl)
sys.exit(1)

# end __main__
96 changes: 96 additions & 0 deletions tests/estimator/sofk/check_properties_h5dat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
#!/usr/bin/env python
import os
import sys
import h5py
import numpy as np
import pandas as pd


def read(fdat):
""" read the scalar.dat file in table format readable by numpy.loadtxt.

The header line should start with '#' and contain column labels.

Args:
dat_fname (str): name of input file
Return:
pd.DataFrame: df containing the table of data
"""
with open(fdat, 'r') as fp:
header = fp.readline()
# end with
cols = header.replace('#', '').split()
df = pd.read_table(fdat, sep='\s+', comment='#', header=None, names=cols)
return df
# end def read


def compare_columns_dat_h5(fdat, fh5):
""" compare mutual data columns in scalar.dat and stat.h5 files

Args:
fdat (str): name of scalar.dat file
fh5 (str): name of stat.h5 file
Return:
dict: a dictionary holding mutual columns names as key
"""

# open database
df = read(fdat)
dat_cols = df.columns

fp = h5py.File(fh5,'r')
h5_cols = fp.keys()

# compare mutual columns in .dat v.s. .h5
agree_map = {} # keep track of which columns agree
for col in h5_cols:
if col not in dat_cols:
continue

# check if col agree between .dat and .h5

# get .h5 values
h5_loc = os.path.join(col, 'value')
h5y = fp[h5_loc].value[:,-1]

# get .dat values
daty = df.loc[:,col].values
agree_map[col] = np.allclose(h5y,daty)
# end for col

# close database
fp.close()

if len(agree_map) == 0:
raise RuntimeError('%s and %s have no mutual column' % (fdat, fh5))

return agree_map
# end def


if __name__ == '__main__':

prefix = sys.argv[1]
seriesl= [0,1]

# check Properties
series_success_map = {}
for iseries in seriesl:

# define files to read
fdat = '%s.s00%d.scalar.dat' % (prefix, iseries)
fh5 = '%s.s00%d.stat.h5' % (prefix, iseries)

agree_map = compare_columns_dat_h5(fdat, fh5)
success = np.all( agree_map.values() )
series_success_map[iseries] = success
# end for iseries

all_success = np.all( series_success_map.values() )
if all_success:
sys.exit(0)
else:
sys.exit(1)

# end __main__
Loading