Skip to content

Commit d0fed09

Browse files
author
dulak
committed
more aims methods
1 parent ad048da commit d0fed09

File tree

1 file changed

+174
-0
lines changed

1 file changed

+174
-0
lines changed

ase/calculators/aims.py

+174
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import numpy as np
1010

11+
from ase.units import Hartree
1112
from ase.io.aims import write_aims, read_aims
1213
from ase.data import atomic_numbers
1314
from ase.calculators.calculator import FileIOCalculator, Parameters, kpts2mp, \
@@ -437,6 +438,179 @@ def read_convergence(self):
437438
converged = True
438439
return converged
439440

441+
def get_number_of_iterations(self):
442+
return self.read_number_of_iterations()
443+
444+
def read_number_of_iterations(self):
445+
niter = None
446+
lines = open(self.out, 'r').readlines()
447+
for n, line in enumerate(lines):
448+
if line.rfind('| Number of self-consistency cycles') > -1:
449+
niter = int(line.split(':')[-1].strip())
450+
return niter
451+
452+
def get_electronic_temperature(self):
453+
return self.read_electronic_temperature()
454+
455+
def read_electronic_temperature(self):
456+
width = None
457+
lines = open(self.out, 'r').readlines()
458+
for n, line in enumerate(lines):
459+
if line.rfind('Occupation type:') > -1:
460+
width = float(line.split('=')[-1].strip().split()[0])
461+
return width
462+
463+
def get_number_of_electrons(self):
464+
return self.read_number_of_electrons()
465+
466+
def read_number_of_electrons(self):
467+
nelect = None
468+
lines = open(self.out, 'r').readlines()
469+
for n, line in enumerate(lines):
470+
if line.rfind('The structure contains') > -1:
471+
nelect = float(line.split()[-2].strip())
472+
return nelect
473+
474+
def get_number_of_bands(self):
475+
return self.read_number_of_bands()
476+
477+
def read_number_of_bands(self):
478+
nband = None
479+
lines = open(self.out, 'r').readlines()
480+
for n, line in enumerate(lines):
481+
if line.rfind('Total number of basis functions') > -1:
482+
nband = int(line.split(':')[-1].strip())
483+
return nband
484+
485+
def get_k_point_weights(self):
486+
return self.read_kpts(mode='k_point_weights')
487+
488+
def get_bz_k_points(self):
489+
raise NotImplementedError
490+
491+
def get_ibz_k_points(self):
492+
return self.read_kpts(mode='ibz_k_points')
493+
494+
def get_spin_polarized(self):
495+
return self.read_number_of_spins()
496+
497+
def get_number_of_spins(self):
498+
return 1 + self.get_spin_polarized()
499+
500+
def read_number_of_spins(self):
501+
spinpol = None
502+
lines = open(self.out, 'r').readlines()
503+
for n, line in enumerate(lines):
504+
if line.rfind('| Number of spin channels') > -1:
505+
spinpol = int(line.split(':')[-1].strip()) - 1
506+
return spinpol
507+
508+
def read_magnetic_moment(self):
509+
magmom = None
510+
if not self.get_spin_polarized():
511+
magmom = 0.0
512+
else: # only for spinpolarized system Magnetisation is printed
513+
for line in open(self.label + '.txt'):
514+
if line.find('Magnetisation') != -1: # last one
515+
magmom = float(line.split('=')[-1].strip())
516+
return magmom
517+
518+
def get_fermi_level(self):
519+
return self.read_fermi()
520+
521+
def get_eigenvalues(self, kpt=0, spin=0):
522+
return self.read_eigenvalues(kpt, spin, 'eigenvalues')
523+
524+
def get_occupations(self, kpt=0, spin=0):
525+
return self.read_eigenvalues(kpt, spin, 'occupations')
526+
527+
def read_fermi(self):
528+
E_f = None
529+
lines = open(self.out, 'r').readlines()
530+
for n, line in enumerate(lines):
531+
if line.rfind('| Chemical potential (Fermi level) in eV') > -1:
532+
E_f = float(line.split(':')[-1].strip())
533+
return E_f
534+
535+
def read_kpts(self, mode='ibz_k_points'):
536+
""" Returns list of kpts weights or kpts coordinates. """
537+
values = []
538+
assert mode in ['ibz_k_points' , 'k_point_weights'], 'mode not in [\'ibz_k_points\' , \'k_point_weights\']'
539+
lines = open(self.out, 'r').readlines()
540+
kpts = None
541+
for n, line in enumerate(lines):
542+
if line.rfind('K-points in task') > -1:
543+
kpts = int(line.split(':')[-1].strip())
544+
kptsstart = n
545+
break
546+
assert not kpts is None
547+
text = lines[kptsstart + 1:]
548+
values = []
549+
for line in text[:kpts]:
550+
if mode == 'ibz_k_points':
551+
b = [float(c.strip()) for c in line.split()[4:7]]
552+
else:
553+
b = float(line.split()[-1])
554+
values.append(b)
555+
if len(values) == 0:
556+
values = None
557+
return np.array(values)
558+
559+
def read_eigenvalues(self, kpt=0, spin=0, mode='eigenvalues'):
560+
""" Returns list of last eigenvalues, occupations
561+
for given kpt and spin. """
562+
values = []
563+
assert mode in ['eigenvalues' , 'occupations'], 'mode not in [\'eigenvalues\' , \'occupations\']'
564+
lines = open(self.out, 'r').readlines()
565+
# number of kpts
566+
kpts = None
567+
for n, line in enumerate(lines):
568+
if line.rfind('K-points in task') > -1:
569+
kpts = int(line.split(':')[-1].strip())
570+
break
571+
assert not kpts is None
572+
assert kpt + 1 <= kpts
573+
# find last (eigenvalues)
574+
eigvalstart = None
575+
for n, line in enumerate(lines):
576+
if line.rfind('Preliminary charge convergence reached') > -1:
577+
eigvalstart = n
578+
break
579+
assert not eigvalstart is None
580+
lines = lines[eigvalstart:]
581+
for n, line in enumerate(lines):
582+
if line.rfind('Writing Kohn-Sham eigenvalues') > -1:
583+
eigvalstart = n
584+
break
585+
assert not eigvalstart is None
586+
text = lines[eigvalstart + 1:] # remove first 1 line
587+
# find the requested k-point
588+
nbands = self.read_number_of_bands()
589+
sppol = self.get_spin_polarized()
590+
beg = (nbands + 4 + int(sppol)*1) * kpt * (sppol + 1) + 3 + sppol * 2 + kpt * sppol
591+
if self.get_spin_polarized():
592+
if spin == 0:
593+
beg = beg
594+
end = beg + nbands
595+
else:
596+
beg = beg + nbands + 5
597+
end = beg + nbands
598+
else:
599+
end = beg + nbands
600+
values = []
601+
for line in text[beg:end]:
602+
# aims prints stars for large values ...
603+
line = line.replace('**************', ' 10000')
604+
b = [float(c.strip()) for c in line.split()[1:]]
605+
values.append(b)
606+
if mode == 'eigenvalues':
607+
values = [Hartree*v[1] for v in values]
608+
else:
609+
values = [v[0] for v in values]
610+
if len(values) == 0:
611+
values = None
612+
return np.array(values)
613+
440614

441615
class AimsCube:
442616
"Object to ensure the output of cube files, can be attached to Aims object"

0 commit comments

Comments
 (0)