lammps/tools/eff/cfg2lammps.py

378 lines
11 KiB
Python
Raw Normal View History

#!/usr/local/bin/python-2.5/bin/python
Info="""
Module name: cfg2lammps.py
Author: (c) Andres Jaramillo-Botero
California Institute of Technology
ajaramil@wag.caltech.edu
Project: pEFF
Version: August 2009
Reads in an eff .cfg file and produces the corresponding lammps data and input files
NOTE: Unsupported functions will be reported in the output log
12/2010: Added support for fixed-core and pseudo-core structures
"""
# import essentials:
import sys, os
from math import log10
from shutil import rmtree
from getopt import gnu_getopt as getopt
import numpy
def printHelp():
print Info
print "Usage: python cfg2lammps cfgfile\n"
return
general="""
# Created %s
# General parameters
variable sname index %s
log ${sname}.log
units electron
newton on
boundary %s
atom_style electron
read_data data.${sname}
pair_style eff/cut %s
pair_coeff * *
compute energies all pair eff/cut
variable eke equal c_energies[1]
variable epauli equal c_energies[2]
variable estatics equal c_energies[3]
variable errestrain equal c_energies[4]
communicate single vel yes
compute peratom all stress/atom
compute p all reduce sum c_peratom[1] c_peratom[2] c_peratom[3]
variable press equal -(c_p[1]+c_p[2]+c_p[3])/(3*vol)
compute effTemp all temp/eff
compute effPress all pressure effTemp
thermo %s
thermo_style custom step etotal pe ke v_eke v_epauli v_estatics v_errestrain temp press v_press
thermo_modify temp effTemp press effPress
"""
#%(date,name,boundary,cutoff,period)
minimize="""
# Minimization
min_style cg
dump 1 %s xyz %s ${sname}.min.xyz
dump 2 %s custom %s ${sname}.min.lammpstrj id type q spin eradius x y z fx fy fz erforce
min_modify line quadratic
minimize 0 1.0e-5 %s %s
undump 1
undump 2
"""
#%(group,period,group,period,iterations,fcalls)
single_pt="""
# Single point energy
run 0
"""
dynamics="""
# %s Dynamics
timestep %s
fix %s
dump 1 %s custom %s ${sname}.%s.lammpstrj id type q spin eradius x y z
dump 2 %s custom %s ${sname}.%s.xyz
run %s
unfix 1
undump 1
undump 2
"""
task={'single_pt':single_pt,'minimize':minimize,'dynamics':dynamics}
q2m={1:'1.007940',2:'4.002602',3:'6.941000',4:'9.012182',5:'10.811000',6:'12.010700',7:'14.006700',8:'15.999400',
9:'18.9984032',10:'20.179700',11:'22.98976928',12:'24.305000',13:'26.9815386',14:'28.085500',15:'30.973762',
16:'32.065000',17:'35.453000',18:'39.948000'}
def generate_lammps_input(infile):
# Defaults values
ensemble={"nve":"1 %s nve/eff",'nvt':"1 %s nvt/eff %s %s %s %s",'npt':"1 %s npt/eff %s %s %s %s %s %s"}
boundary="f f f"
xbound="-1000.000 1000.0 xlo xhi\n"
ybound="-1000.000 1000.0 ylo yhi\n"
zbound="-1000.000 1000.0 zlo zhi\n"
cutoff=1000.0
period="1"
emass=0
vels=""
datafile=open("data."+infile[:-4],'w')
scriptfile=open("in."+infile[:-4],'w')
print "Reading %s ... [WAIT]"%infile,
fin = open(infile,'r')
lines = fin.xreadlines()
print 7*"\b"+"[DONE]"
numcores=0
numnuclei=0
numelec=0
cores={}
nuclei={}
electrons={}
masses=[]
massstr="Masses\n\n"
types=1
q2type={}
Tflag=False # Default ensemble is NVE
steps='1000'
print "Extracting run parameters from %s ... "%(infile),
for line in lines:
# 1st level keywords
if line.find("@params")==0:
flag='params'
continue
elif line.find("@cores")==0:
flag='cores'
continue
elif line.find("@nuclei")==0:
flag='nuclei'
continue
elif line.find("@electrons")==0:
flag='electrons'
continue
elif line.find("@nuc_velocities")==0:
flag='n_vels'
continue
elif line.find("@elec_velocities")==0:
flag='e_vels'
continue
elif line.find("@nuc_masses")==0:
flag='n_mass'
continue
elif line.find("@elec_masses")==0:
flag='e_mass'
continue
elif line.find("@restraints")==0:
flag='restraints'
continue
# 2nd level keywords
if flag=='params':
if line.find("calc")>=0:
op=line.split()[2]
if line.find("print_every")>=0:
period=line.split()[2]
if line.find("num_steps")>=0:
steps=line.split()[2]
if line.find("min_freeze")>=0:
setforce="velocity\t% set 0.0 0.0 0.0\nfix\tfreeze %s setforce 0.0 0.0 0.0"%(line.split()[2],line.split()[2])
if line.find("thermostat")>=0:
tflag=True
#ensemble="fix\t1 all nvt/eff "
if line.find("start_temperature")>=0:
Tstart=line.split()[2]
#ensemble+=Tstart
if line.find("end_temperature")>=0:
Tstop=line.split()[2]
#ensemble+=Tstop
if line.find("andersen_coupling")>=0 or line.find("nose_hoover_coupling")>=0:
Tdamp=line.split()[2]
#ensemble+=Tdamp
if line.find("dt")>=0:
dt=line.split()[2]
if line.find("electron_mass")>=0:
emass=line.split()[2]
if line.find("adaptive_step_size")>=0:
continue
if line.find("adaptive_energy")>=0:
continue
if line.find("e_field_freq")>=0:
continue
if line.find("e_field_packet_duration")>=0:
continue
if line.find("e_field")>=0:
field=line.split()[2:5]
efield="fix\field all efield %s %s %s"%(field[0],field[1],field[2])
if line.find("e_field_packet_duration")>=0:
continue
if line.find("set_limit")>=0:
2017-03-06 07:30:39 +08:00
continue # need to add this constraint
if line.find("set_limit_stiffness")>=0:
continue
if line.find("output_position")>=0:
dump_pos="dump\t1 all custom %s ${sname}.lammpstrj id type q spin eradius x y z "%(period)
if line.find("output_velocities")>=0:
dump_pos+="vx vy vz "
if line.find("output_energy_forces")>=0:
dump_pos="compute\tenergy all pe/atom\n"+dump_pos
dump_pos+="c_energy fx fy fz\n"
if line.find("output_restart")>=0:
restart="restart\t%s ${sname}.restart1 ${sname}.restart2"%(period)
if line.find("output_restraints")>=0:
continue
if line.find("ewald_re_cutoff")>=0 or line.find("ewald_autoset")>=0 or line.find("ewald_log_precision")>=0 or line.find("ewald_max_re")>=0 or \
line.find("ewald_r_cutoff")>=0 or line.find("ewald_k_cutoff")>=0 or line.find("ewald_nuc_r")>=0:
continue
if line.find("periodic")>=0:
bounds=line.split()[2]
if bounds=="True": boundary="p p p"
elif bounds=="minimage_x": boundary="p f f"
elif bounds=="minimage_xy": boundary="p p f"
elif bounds=="minimage_y": boundary="f p f"
elif bounds=="minimage_xyz": boundary="p p p"
elif bounds=="minimage_z": boundary="f f p"
if line.find("x_bound")>=0:
xbnds=line.split()[2:4]
xbound="%s %s xlo xhi\n"%(xbnds[0],xbnds[1])
if line.find("y_bound")>=0:
ybnds=line.split()[2:4]
ybound="%s %s ylo yhi\n"%(ybnds[0],ybnds[1])
if line.find("z_bound")>=0:
zbnds=line.split()[2:4]
zbound="%s %s zlo zhi\n"%(zbnds[0],zbnds[1])
if line.find("taper_cutoff")>=0:
cutoff=line.split()[2]
continue
if flag=='cores' and len(line)>1:
numcores+=1
ln=line.split()
nc=' '.join(ln[0:3])
q=ln[3]
spin='3'
radius=ln[4]
m=q2m[int(float(q))]
if m not in masses:
masses.append(m)
massstr+="%d %s\n"%(types,m)
q2type[q]=types
types+=1
cores[numcores]=[nc,q,spin,radius]
continue
if flag=='nuclei' and len(line)>1:
numnuclei+=1
ln=line.split()
np=' '.join(ln[0:3])
q=ln[3]
m=q2m[int(float(q))]
if m not in masses:
masses.append(m)
massstr+="%d %s\n"%(types,m)
q2type[q]=types
types+=1
nuclei[numnuclei]=[np,q]
continue
if flag=='electrons' and len(line)>1:
numelec+=1
ln=line.split()
ep=' '.join(ln[0:3])
spin=ln[3]
radius=ln[4]
electrons[numelec]=[ep,spin,radius]
if numelec==1:
if emass!=0: massstr+="%d %s\n\n"%(types,emass) # electron mass=1
else: massstr+="%d 1.000000\n\n"%(types)
continue
if flag=='n_vels' and len(line)>1:
vels+=line+" 0.0"
continue
if flag=='e_vels' and len(line)>1:
ln=line.split()
ln[0]=ln[0]+numnuclei
vels+=ln[0]+" "+ln[1]+" "+ln[2]+" "+ln[3]+" "+ln[4]+"\n"
continue
if flag=='n_mass' and len(line)>1:
print "Setting nuclear masses is unsupported\n"
continue
if flag=='e_mass' and len(line)>1:
print "Setting electron masses is unsupported\n"
continue
print "\bDone"
# Build data file
print "Writing datafile to %s ... "%('data.'+infile),
sys.stdout.flush()
print "\b"*19+"General section ",
datafile.writelines("Created using cfg2lammps (c) AJB-2009\n\n%d atoms\n%d atom types\n\n%s%s%s\n"%(numcores+numnuclei+numelec,types,xbound,ybound,zbound))
print "\b"*19+"Masses section ",
datafile.writelines(massstr)
print "\b"*19+"Atoms section ",
datafile.writelines("Atoms\n\n")
for n in range(numcores):
datafile.writelines("%d %d %2.2f %s %s %s\n"%(n+1,q2type[cores[n+1][1]],float(cores[n+1][1]),cores[n+1][2],cores[n+1][3],cores[n+1][0]))
for n in range(numnuclei):
datafile.writelines("%d %d %2.2f 0 0.0 %s\n"%(n+numcores+1,q2type[nuclei[n+1][1]],float(nuclei[n+1][1]),nuclei[n+1][0]))
for e in range(numelec):
datafile.write("%d %d 0.0 %s %s %s\n"%(e+numnuclei+numcores+1,types,electrons[e+1][1],electrons[e+1][2],electrons[e+1][0]))
print "\b"*19+"Velocities section\n",
datafile.writelines(vels)
datafile.writelines("\n")
print "DONE .... GOODBYE !!"
datafile.close()
# Build input script
import datetime
scriptfile.writelines(general%(datetime.date.today(),infile[:-4],boundary,cutoff,period))
if op=='minimize':
scriptfile.writelines(minimize%('all',period,'all',period,steps,'10000'))
#%(group,period,group,period,iterations,fcalls)
elif op=='single_pt':
scriptfile.writelines(single_pt%())
elif op=='dynamics':
if Tflag==True:
scriptfile.writelines(dynamics%('NVT',dt,ensemble['nvt']%('all',Tstart,Tstop,Tdamp,''),'all',period,'nvt','all',period,'nve',steps))
#%(ensemble,dt,group,ensemble%(group,tstart,tstop,tdamp,options))
else:
scriptfile.writelines(dynamics%('NVE',dt,ensemble['nve']%('all'),'all',period,'nve','all',period,'nve',steps))
#%(ensemble,dt,group,ensemble%(group))
scriptfile.writelines("\n")
if __name__ == '__main__':
# set defaults
# check for input:
opts, argv = getopt(sys.argv[1:], 'h')
# if no input, print help and exit
if len(argv) != 1:
printHelp()
sys.exit(1)
else:
infile=argv[0]
# read options
for opt, arg in opts:
if opt == '-h': # -h: print help
printHelp()
generate_lammps_input(infile)