1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240
|
#!/usr/bin/python
import sys, string
if len(sys.argv)<2 or len(sys.argv)>11:
print 'Usage: python comp_band_abinit2elk.py [abinit _EIG file] ...'
print ' ... [elk BAND.OUT file] [align #kpt #band] ...'
print ' ... [nbdbuf #] [Fermi #abinit #elk]'
print ' (align, eV, nbdbuf and Fermi sections optional)'
sys.exit()
# Check arguments
eVconv = ''
str_nbdbuf = ''
nbdbuf = 0
align_values = 0
align_ikpt = 0
align_iband = 0
align_values_fermi = 0
align_abinit_fermi = 0.0
align_elk_fermi = 0.0
iarg = 3
while iarg < len(sys.argv):
if str(sys.argv[iarg])=='eV':
eVconv = str(sys.argv[iarg]) # Assume Ha values and convert to eV
print '# Values assumed to be in Ha and converted to eV'
if str(sys.argv[iarg])=='align':
align_values = 1
align_ikpt = int(sys.argv[iarg+1])
align_iband = int(sys.argv[iarg+2])
print '# Values aligned at kpt:','%4i'%align_ikpt,\
' and band:','%4i'%align_iband
iarg = iarg + 2
if (str(sys.argv[iarg])=='Fermi' or \
str(sys.argv[iarg])=='fermi'): # Align Fermi energies
align_values_fermi = 1
align_abinit_fermi = float(sys.argv[iarg+1])
align_elk_fermi = float(sys.argv[iarg+2])
iarg = iarg + 2
if str(sys.argv[iarg])=='nbdbuf':
nbdbuf = int(sys.argv[iarg+1])
print '# nbdbuf set, last:','%4i'%nbdbuf,' bands will be ignored'
iarg = iarg + 1
iarg = iarg + 1
# Parse abinit file
input_file1_name = str(sys.argv[1]) # name of first input file (first argument)
input_file1_r = open(input_file1_name,'r') # open it as read file
abinit_file_data = input_file1_r.readlines()
input_file1_r.close()
# Read in k-point data as a list of numbers, by k-point
abinit_band_data = []
k_point_list = []
for iline in range(2,len(abinit_file_data)):
# Skip line if it is a k-point spec.
if abinit_file_data[iline].find('kpt#') > -1:
continue
# Accumulate values
new_values = map(float,string.split(abinit_file_data[iline]))
k_point_list.extend(new_values)
# If we are on last line, finish appending
if iline == len(abinit_file_data)-1:
abinit_band_data.append(k_point_list)
break
# If the next line is a k-point spec., append.
if abinit_file_data[iline+1].find('kpt#') > -1:
abinit_band_data.append(k_point_list)
k_point_list = []
continue
#print 'nkpt:',len(abinit_band_data)
#print 'nbnds:',len(abinit_band_data[0])
nkpt = len(abinit_band_data)
nbands = len(abinit_band_data[0])
# Initialise variables for elk file
input_file2_name = str(sys.argv[2]) # name of second input file(second argument)
input_file2_r = open(input_file2_name, "r") # open it as read file
# If alignment is done, parse elk file and find alignment value
if align_values:
elk_file_data = input_file2_r.readlines()
band = 0
kpt = -1
previous_kpt_val = -1.0
for iline in range(0,len(elk_file_data)-1):
kpt = kpt + 1
if string.split(elk_file_data[iline]) == []: # skip blank lines
kpt = -1
band = band + 1
continue
val_list = map(float,string.split(elk_file_data[iline]))
elk_align_value = val_list[1]
if previous_kpt_val==elk_align_value: # skip repeated kpts
kpt = kpt - 1
band = band - 1
continue
if kpt+1==align_ikpt and band+1==align_iband:
break
abinit_align_value = abinit_band_data[align_ikpt-1][align_iband-1]
print '# Abinit alignment value: ',\
'%18.9E'%abinit_align_value
print '# Elk alignment value: ',\
'%18.9E'%elk_align_value
input_file2_r.close()
input_file2_r = open(input_file2_name, "r")
# If Fermi alignment is done, print info
if align_values_fermi:
print '# Abinit Fermi energy (Ha): ',\
'%18.9E'%align_abinit_fermi
print '# Elk Fermi energy (Ha): ',\
'%18.9E'%align_elk_fermi
print '# k-point abinit val elk val diff %diff'
# Now we begin the reading and comparison of the data
Ha_to_eV = 27.21138386
avg_diff = 0.0
avg_percentage = 0.0
nvals = 0
min_diff = 1000000000.0
max_diff = -100000000.0
input_file2_current_line='\n'
band = 0
kpt = -1
previous_kpt_val = -1.0
reset_done = 1
while input_file2_current_line.endswith('\n'):
kpt = kpt + 1
#print kpt
input_file2_current_line = input_file2_r.readline()
if not input_file2_current_line.endswith('\n'): # stop at last line
break
if string.split(input_file2_current_line) == []: # skip blank lines
kpt = -1
band = band + 1
if band == nbands-nbdbuf:
break
print ' '
continue
# Parse the records of the lines
numbers_list2 = []
numbers2 = map(float, string.split(input_file2_current_line))
numbers_list2.extend(numbers2)
# Cycle if k-point value is repeated in elk
if numbers_list2[0] == previous_kpt_val:
kpt = kpt - 1
continue
previous_kpt_val = numbers_list2[0]
# Calculate difference,average,max,min
if align_values:
abinit_band_data[kpt][band] = abinit_band_data[kpt][band] \
- abinit_align_value
numbers_list2[1] = numbers_list2[1] - elk_align_value
if align_values_fermi:
abinit_band_data[kpt][band] = abinit_band_data[kpt][band] \
- align_abinit_fermi
numbers_list2[1] = numbers_list2[1] - align_elk_fermi
if eVconv=='eV':
abinit_band_data[kpt][band] = abinit_band_data[kpt][band]*Ha_to_eV
numbers_list2[1] = numbers_list2[1]*Ha_to_eV
diff = numbers_list2[1] - abinit_band_data[kpt][band]
if numbers_list2[1]!=0.0:
percentage = (abinit_band_data[kpt][band]/numbers_list2[1] - 1.0)*100.0
else:
percentage = 0.0
avg_diff = avg_diff + abs(diff)
avg_percentage = avg_percentage + abs(percentage)
nvals = nvals + 1
if diff<min_diff:
min_diff = diff
min_percentage = percentage
if diff>max_diff:
max_diff = diff
max_percentage = percentage
if align_values and band+1==align_iband and reset_done: # Save current averages for the
occ_avg_diff = avg_diff # occupied states and reset
occ_avg_percentage = avg_percentage
occ_min_diff = min_diff
occ_min_percentage = min_percentage
occ_max_diff = max_diff
occ_max_percentage = max_percentage
occ_nvals = nvals
nvals = 0
avg_diff = 0.0
avg_percentage = 0.0
min_diff = 1000000000.0
max_diff = -100000000.0
reset_done = 0
# Print the output data
if abs(abinit_band_data[kpt][band])<0.1 or abs(numbers_list2[1])<0.1:
print '%14.9f'%numbers_list2[0],'%18.9E'%abinit_band_data[kpt][band],\
'%18.9E'%numbers_list2[1],'%12.3E'%diff,' (','%7.3f'%percentage,'%)'
else:
print '%14.9f'%numbers_list2[0],'%14.9f'%abinit_band_data[kpt][band],\
'%18.9f'%numbers_list2[1],'%16.3E'%diff,' (','%7.3f'%percentage,'%)'
input_file2_r.close
avg_diff = avg_diff/float(nvals)
avg_percentage = avg_percentage/float(nvals)
if eVconv=='eV':
eVconv=' eV'
else:
eVconv=' Ha'
if align_values:
occ_avg_diff = occ_avg_diff/float(occ_nvals)
occ_avg_percentage = occ_avg_percentage/float(occ_nvals)
print '#'
print '# AVERAGES FOR OCCUPIED STATES:'
print '# nvals:','%5i'%occ_nvals
print '# average diff:','%12.6F'%occ_avg_diff,eVconv
print '# minimum diff:','%12.6F'%occ_min_diff,eVconv
print '# maximum diff:','%12.6F'%occ_max_diff,eVconv
print '#'
print '# AVERAGES FOR UNOCCUPIED STATES:'
print '# nvals:','%5i'%nvals
print '# average diff:','%12.6F'%avg_diff,eVconv
print '# minimum diff:','%12.6F'%min_diff,eVconv
print '# maximum diff:','%12.6F'%max_diff,eVconv
print '#'
print '# NOTE: Abinit values are read in fixed format with five decimal'
print '# places. For low values, ~E-04 or ~E-03 may be the highest'
print '# precision you can get.'
else:
print '# nvals:','%5i'%nvals
print '# average diff:','%12.6F'%avg_diff,eVconv
print '# minimum diff:','%12.6F'%min_diff,eVconv
print '# maximum diff:','%12.6F'%max_diff,eVconv
print '#'
print '# NOTE: Abinit values are read in fixed format with five decimal'
print '# places. For low values, ~E-04 or ~E-03 may be the highest'
print '# precision you can get.'
|