#!/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: 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)