qmcchem/src/MAIN/admc.py

126 lines
2.9 KiB
Python
Executable File

#!/usr/bin/env python3
from mpi4py import MPI
import sys
import gzip
import random
import math
import subprocess
admc_exec = "/home/scemama/qmcchem/src/MAIN/admc"
n_walk_per_proc = 10
def start():
return subprocess.Popen(
[ admc_exec, sys.argv[1] ],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
def read(process,len_walk):
line = process.stdout.readline().decode("utf-8").strip()
walk_num = int(line)
walkers = []
print(walk_num)
for k in range(walk_num):
w = []
for i in range(len_walk):
line = process.stdout.readline().decode("utf-8").strip()
w.append( line )
w = '\n'.join(w)
walkers.append(w)
_, E, W = process.stdout.readline().decode("utf-8").split()
return walkers, float(E), float(W)
def write(process, message):
process.stdin.write(f"{message}\n".encode("utf-8"))
process.stdin.flush()
def terminate(process):
process.stdin.close()
process.terminate()
process.wait(timeout=0.2)
def print_energy(EnergyWeight, Energy2Weight, Weight, N):
e = EnergyWeight / Weight
e2 = Energy2Weight / Weight
err = math.sqrt(abs(e*e - e2) / max(1,(N-1)) )
print("%f +/- %f"%(e, err))
return err
def main():
try:
input_dir = sys.argv[1]
except:
print("syntax: argv[0] [FILE]")
sys.exit(-1)
# Pool of electron coordinates
with gzip.open(input_dir+"/electrons/elec_coord_pool.gz","r") as f:
data = f.read().decode("utf-8").split()
len_walk = int(data[1])*int(data[2])
icount = 0
buffer = []
walkers = []
for d in data[4:]:
buffer.append(d)
icount += 1
if (icount == len_walk):
walkers.append(buffer)
buffer = []
icount = 0
walkers = [ '\n'.join(x) for x in walkers ]
do_loop = True
EnergyWeight = 0.
Energy2Weight = 0.
Weight = 0.
NSamples = 0.
# Start processes
proc = start()
while do_loop:
# Once every 1000, shuffle the list of walkers
if random.random() < 0.01:
print("SHUFFLE")
random.shuffle(walkers)
# Pick new walkers
new_coords = walkers[:n_walk_per_proc]
walkers = walkers[n_walk_per_proc:]
# Send new walkers to the process
write(proc, '\n'.join(new_coords))
# Fetch new walkers from the process
new_coords, e_new, w_new = read(proc, len_walk)
walkers += new_coords
# Print energy
ew = e_new * w_new
EnergyWeight += ew
Energy2Weight += e_new * ew
Weight += w_new
NSamples += 1.
print (len(walkers))
err = print_energy(EnergyWeight, Energy2Weight, Weight, NSamples)
if err < 1.e-3:
do_loop = False
terminate(proc)
return
if __name__ == "__main__":
main()