Module ctoolkit.VASP.POSCAR
Expand source code
from toolkit.global_vars.ext_libs import *
from toolkit.global_vars.decorators import *
from toolkit.tools import tools
# Subclass POSCAR
class POSCAR():
# Value initialization
def __init__(self, mothership):
self.tools = tools.tools()
self.title = '\n'
self.B = np.zeros([3,3], dtype=float)
self.a_lat = 0
self.names = []
self.namelist = []
self.atom_id = []
self.lattype = '\n'
self.multiplicity = [0]
self.volume = 0.0
self.at_frac = np.array(np.array([.0, .0, .0], dtype=float))
self.at_cart = np.array(np.array([.0, .0, .0], dtype=float))
self.type = "VASP"
self.mothership = mothership
self.is_filled = False
# Generate a sample POSCAR from input python parameters
def generate_poscar(self, B, alat, names, mult, atoms_frac, system_name='Generated by the Crystal Toolkit'):
self.title = system_name + '\n'
self.B = B
self.a_lat = alat
self.names = names
self.lattype = 'Direct\n'
self.multiplicity = mult
self.volume = np.linalg.det(self.B)
self.at_frac = atoms_frac
self.at_cart = self.tools.frac_to_cart(self.B, self.at_frac)
self.is_filled = True
# Read from POSCAR file
@calculate_time
def read_poscar(self, filename=None):
if filename: self.poscar_filename = filename
else: self.poscar_filename = sys.argv[1]
fopen = open(self.poscar_filename,'r')
lines = fopen.readlines()
fopen.close()
self.title = lines[0]
self.a_lat = float(lines[1].split()[0])
for i in range(3):
self.B[i,:] = np.array(lines[2+i].split()[:],dtype=float)*self.a_lat
self.names = lines[5].split()
self.multiplicity = np.array(lines[6].split()[:], dtype=int)
ct = 0
# We need to initialize self.namelist into a list
# in case read_poscar() is called multiple times
self.namelist = []
for i, name in enumerate(self.names):
for atom in range(self.multiplicity[i]):
self.namelist.append(self.names[i])
self.atom_id.append(ct)
ct += 1
numatoms = ct
self.lattype = lines[7]
at_frac_list = []
at_cart_list = []
for line in lines[8:8+numatoms]:
vec_now = np.array(line.split()[:], dtype=float)
at_frac_list.append(vec_now)
self.at_frac = np.copy(np.array(at_frac_list, dtype=float))
# Postprocessing
self.frac_image_sniper()
self.at_cart = np.array(self.tools.frac_to_cart(self.B, self.at_frac), dtype=float)
self.volume = np.linalg.det(self.B)
self.namelist = np.array(self.namelist)
self.is_filled = True
# A function to put back to the box atoms that slipped away
@calculate_time
def frac_image_sniper(self):
tol = 0.05
self.at_frac[np.abs(self.at_frac - 1.0) < tol] -= 1.0
# Reprocess POSCAR if BASIS is changed
@calculate_time
def recalculate_poscar(self):
self.at_frac = np.copy(self.tools.cart_to_frac(self.B, self.at_cart))
self.frac_image_sniper()
self.at_cart = np.copy(self.tools.frac_to_cart(self.B, self.at_frac))
# Apply a rigid displacement. Can be moved to the toolbox.
@calculate_time
def rigid_displacement(self, vector):
self.tools.rigid_displacement(vector, self)
# Update basis of the POSCAR structure
@calculate_time
def update_B(self, B=None):
if B is None: pass
else: self.B = np.copy(np.array(B, dtype=float))
self.volume = np.linalg.det(self.B)
self.mothership.outcar.volume = np.linalg.det(self.B)
# Directly give distances in \AA by providing
# indices of the atoms in the poscar.
def cart_dist(self, a, b):
vec_a = self.at_cart[a]
vec_b = self.at_cart[b]
bestperiodic, key = self.tools.findBestPairPeriodic(fixed_atom=vec_a, periodic_atom=vec_b, basis=self.B)
return np.sqrt(np.dot(vec_a-bestperiodic, vec_a-bestperiodic))
# Atom selection tool. Returns atoms with "name" labels.
@calculate_time
def filter_atoms(self, name, mode='cart', excludeSatList=[]):
num_atoms = len(self.namelist[self.namelist == name])
at_frac = []#np.zeros([num_atoms-len(excludeSatList), 3], dtype=float)
at_cart = []#np.zeros([num_atoms-len(excludeSatList), 3], dtype=float)
ct_name = 0
for i in range(len(self.at_frac)):
if i in excludeSatList: continue
if self.namelist[i] == name:
#at_frac[ct_name] = self.at_frac[i]
#at_cart[ct_name] = self.at_cart[i]
at_frac.append(self.at_frac[i])
at_cart.append(self.at_cart[i])
ct_name += 1
at_frac, at_cart = np.array(at_frac), np.array(at_cart)
#print("ctname", ct_name, len(at_frac), len(at_cart))
if mode == 'frac':
return at_frac
if mode == 'cart':
return at_cart
# Atom selection tool 2. Return an iterable list of
# the filtered atoms by "name".
@calculate_time
def filter_atoms_list(self, name, excludeSatList=[]):
atom_list = []
for i in range(len(self.namelist)):
if ((self.namelist[i] == name) and
(i not in excludeSatList)):
atom_list.append(i)
return atom_list
# Make the selected atoms be represented by their
# image closest to a chosen point in space
def make_whole_point(self, atomlist, point):
for atom in atomlist:
bestperiodic, key = self.tools.findBestPairPeriodic(fixed_atom=point, periodic_atom=self.at_cart[atom], basis=self.B)
self.at_frac[atom] = self.tools.cart_to_frac(self.B, bestperiodic)
self.at_cart[atom] = bestperiodic
# Function that prints the POSCAR in frac format
@calculate_time
def write_frac(self, filename=None):
s = ''
s += (self.title)
s += '%s\n' % (self.a_lat)
s += '%12.8f %12.8f %12.8f\n' % (self.B[0,0], self.B[0,1], self.B[0,2])
s += '%12.8f %12.8f %12.8f\n' % (self.B[1,0], self.B[1,1], self.B[1,2])
s += '%12.8f %12.8f %12.8f\n' % (self.B[2,0], self.B[2,1], self.B[2,2])
for name in self.names:
s += '%5s' % (name)
s += '\n'
for mult in self.multiplicity:
s += '%5d ' % (mult)
s += '\n'
s += self.lattype
for atom in range(len(self.at_frac)):
for i in range(3):
s += '%12.8f' % (self.at_frac[atom,i])
if atom < len(self.at_frac)-1 : s += '\n'
if filename:
fopen = open(filename,'w')
fopen.write(s)
fopen.close()
return s
# Function that prints the POSCAR in cart format
@calculate_time
def write_cart(self, filename=None):
s = ''
s += (self.title)
s += '%s\n' % (self.a_lat)
s += '\t%.8f %.8f %.8f\n' % (self.B[0,0], self.B[0,1], self.B[0,2])
s += '\t%.8f %.8f %.8f\n' % (self.B[1,0], self.B[1,1], self.B[1,2])
s += '\t%.8f %.8f %.8f\n' % (self.B[2,0], self.B[2,1], self.B[2,2])
for name in self.names:
s += '\t%s\t' % (name)
s += '\n'
for mult in self.multiplicity:
s += '\t%d\t' % (mult)
s += '\n'
s += 'Cartesian\n'
for atom in range(len(self.at_cart)):
s += '\t%.8f\t%.8f\t%.8f' % (self.at_cart[atom, 0], self.at_cart[atom, 1], self.at_cart[atom, 2])
if atom < len(self.at_cart)-1 : s += '\n'
if filename:
fopen = open(filename,'w')
fopen.write(s)
fopen.close()
return s
Classes
class POSCAR (mothership)
-
Expand source code
class POSCAR(): # Value initialization def __init__(self, mothership): self.tools = tools.tools() self.title = '\n' self.B = np.zeros([3,3], dtype=float) self.a_lat = 0 self.names = [] self.namelist = [] self.atom_id = [] self.lattype = '\n' self.multiplicity = [0] self.volume = 0.0 self.at_frac = np.array(np.array([.0, .0, .0], dtype=float)) self.at_cart = np.array(np.array([.0, .0, .0], dtype=float)) self.type = "VASP" self.mothership = mothership self.is_filled = False # Generate a sample POSCAR from input python parameters def generate_poscar(self, B, alat, names, mult, atoms_frac, system_name='Generated by the Crystal Toolkit'): self.title = system_name + '\n' self.B = B self.a_lat = alat self.names = names self.lattype = 'Direct\n' self.multiplicity = mult self.volume = np.linalg.det(self.B) self.at_frac = atoms_frac self.at_cart = self.tools.frac_to_cart(self.B, self.at_frac) self.is_filled = True # Read from POSCAR file @calculate_time def read_poscar(self, filename=None): if filename: self.poscar_filename = filename else: self.poscar_filename = sys.argv[1] fopen = open(self.poscar_filename,'r') lines = fopen.readlines() fopen.close() self.title = lines[0] self.a_lat = float(lines[1].split()[0]) for i in range(3): self.B[i,:] = np.array(lines[2+i].split()[:],dtype=float)*self.a_lat self.names = lines[5].split() self.multiplicity = np.array(lines[6].split()[:], dtype=int) ct = 0 # We need to initialize self.namelist into a list # in case read_poscar() is called multiple times self.namelist = [] for i, name in enumerate(self.names): for atom in range(self.multiplicity[i]): self.namelist.append(self.names[i]) self.atom_id.append(ct) ct += 1 numatoms = ct self.lattype = lines[7] at_frac_list = [] at_cart_list = [] for line in lines[8:8+numatoms]: vec_now = np.array(line.split()[:], dtype=float) at_frac_list.append(vec_now) self.at_frac = np.copy(np.array(at_frac_list, dtype=float)) # Postprocessing self.frac_image_sniper() self.at_cart = np.array(self.tools.frac_to_cart(self.B, self.at_frac), dtype=float) self.volume = np.linalg.det(self.B) self.namelist = np.array(self.namelist) self.is_filled = True # A function to put back to the box atoms that slipped away @calculate_time def frac_image_sniper(self): tol = 0.05 self.at_frac[np.abs(self.at_frac - 1.0) < tol] -= 1.0 # Reprocess POSCAR if BASIS is changed @calculate_time def recalculate_poscar(self): self.at_frac = np.copy(self.tools.cart_to_frac(self.B, self.at_cart)) self.frac_image_sniper() self.at_cart = np.copy(self.tools.frac_to_cart(self.B, self.at_frac)) # Apply a rigid displacement. Can be moved to the toolbox. @calculate_time def rigid_displacement(self, vector): self.tools.rigid_displacement(vector, self) # Update basis of the POSCAR structure @calculate_time def update_B(self, B=None): if B is None: pass else: self.B = np.copy(np.array(B, dtype=float)) self.volume = np.linalg.det(self.B) self.mothership.outcar.volume = np.linalg.det(self.B) # Directly give distances in \AA by providing # indices of the atoms in the poscar. def cart_dist(self, a, b): vec_a = self.at_cart[a] vec_b = self.at_cart[b] bestperiodic, key = self.tools.findBestPairPeriodic(fixed_atom=vec_a, periodic_atom=vec_b, basis=self.B) return np.sqrt(np.dot(vec_a-bestperiodic, vec_a-bestperiodic)) # Atom selection tool. Returns atoms with "name" labels. @calculate_time def filter_atoms(self, name, mode='cart', excludeSatList=[]): num_atoms = len(self.namelist[self.namelist == name]) at_frac = []#np.zeros([num_atoms-len(excludeSatList), 3], dtype=float) at_cart = []#np.zeros([num_atoms-len(excludeSatList), 3], dtype=float) ct_name = 0 for i in range(len(self.at_frac)): if i in excludeSatList: continue if self.namelist[i] == name: #at_frac[ct_name] = self.at_frac[i] #at_cart[ct_name] = self.at_cart[i] at_frac.append(self.at_frac[i]) at_cart.append(self.at_cart[i]) ct_name += 1 at_frac, at_cart = np.array(at_frac), np.array(at_cart) #print("ctname", ct_name, len(at_frac), len(at_cart)) if mode == 'frac': return at_frac if mode == 'cart': return at_cart # Atom selection tool 2. Return an iterable list of # the filtered atoms by "name". @calculate_time def filter_atoms_list(self, name, excludeSatList=[]): atom_list = [] for i in range(len(self.namelist)): if ((self.namelist[i] == name) and (i not in excludeSatList)): atom_list.append(i) return atom_list # Make the selected atoms be represented by their # image closest to a chosen point in space def make_whole_point(self, atomlist, point): for atom in atomlist: bestperiodic, key = self.tools.findBestPairPeriodic(fixed_atom=point, periodic_atom=self.at_cart[atom], basis=self.B) self.at_frac[atom] = self.tools.cart_to_frac(self.B, bestperiodic) self.at_cart[atom] = bestperiodic # Function that prints the POSCAR in frac format @calculate_time def write_frac(self, filename=None): s = '' s += (self.title) s += '%s\n' % (self.a_lat) s += '%12.8f %12.8f %12.8f\n' % (self.B[0,0], self.B[0,1], self.B[0,2]) s += '%12.8f %12.8f %12.8f\n' % (self.B[1,0], self.B[1,1], self.B[1,2]) s += '%12.8f %12.8f %12.8f\n' % (self.B[2,0], self.B[2,1], self.B[2,2]) for name in self.names: s += '%5s' % (name) s += '\n' for mult in self.multiplicity: s += '%5d ' % (mult) s += '\n' s += self.lattype for atom in range(len(self.at_frac)): for i in range(3): s += '%12.8f' % (self.at_frac[atom,i]) if atom < len(self.at_frac)-1 : s += '\n' if filename: fopen = open(filename,'w') fopen.write(s) fopen.close() return s # Function that prints the POSCAR in cart format @calculate_time def write_cart(self, filename=None): s = '' s += (self.title) s += '%s\n' % (self.a_lat) s += '\t%.8f %.8f %.8f\n' % (self.B[0,0], self.B[0,1], self.B[0,2]) s += '\t%.8f %.8f %.8f\n' % (self.B[1,0], self.B[1,1], self.B[1,2]) s += '\t%.8f %.8f %.8f\n' % (self.B[2,0], self.B[2,1], self.B[2,2]) for name in self.names: s += '\t%s\t' % (name) s += '\n' for mult in self.multiplicity: s += '\t%d\t' % (mult) s += '\n' s += 'Cartesian\n' for atom in range(len(self.at_cart)): s += '\t%.8f\t%.8f\t%.8f' % (self.at_cart[atom, 0], self.at_cart[atom, 1], self.at_cart[atom, 2]) if atom < len(self.at_cart)-1 : s += '\n' if filename: fopen = open(filename,'w') fopen.write(s) fopen.close() return s
Methods
def cart_dist(self, a, b)
-
Expand source code
def cart_dist(self, a, b): vec_a = self.at_cart[a] vec_b = self.at_cart[b] bestperiodic, key = self.tools.findBestPairPeriodic(fixed_atom=vec_a, periodic_atom=vec_b, basis=self.B) return np.sqrt(np.dot(vec_a-bestperiodic, vec_a-bestperiodic))
def filter_atoms(*args, **kwargs)
-
Expand source code
def inner1(*args, **kwargs): # storing time before function execution begin = time.time() val = func(*args, **kwargs) # storing time after function execution end = time.time() timer_name = func.__name__ timer_time = end-begin if timer_name in timers_dict: timers_dict[timer_name] += timer_time else: timers_dict[timer_name] = timer_time return val
def filter_atoms_list(*args, **kwargs)
-
Expand source code
def inner1(*args, **kwargs): # storing time before function execution begin = time.time() val = func(*args, **kwargs) # storing time after function execution end = time.time() timer_name = func.__name__ timer_time = end-begin if timer_name in timers_dict: timers_dict[timer_name] += timer_time else: timers_dict[timer_name] = timer_time return val
def frac_image_sniper(*args, **kwargs)
-
Expand source code
def inner1(*args, **kwargs): # storing time before function execution begin = time.time() val = func(*args, **kwargs) # storing time after function execution end = time.time() timer_name = func.__name__ timer_time = end-begin if timer_name in timers_dict: timers_dict[timer_name] += timer_time else: timers_dict[timer_name] = timer_time return val
def generate_poscar(self, B, alat, names, mult, atoms_frac, system_name='Generated by the Crystal Toolkit')
-
Expand source code
def generate_poscar(self, B, alat, names, mult, atoms_frac, system_name='Generated by the Crystal Toolkit'): self.title = system_name + '\n' self.B = B self.a_lat = alat self.names = names self.lattype = 'Direct\n' self.multiplicity = mult self.volume = np.linalg.det(self.B) self.at_frac = atoms_frac self.at_cart = self.tools.frac_to_cart(self.B, self.at_frac) self.is_filled = True
def make_whole_point(self, atomlist, point)
-
Expand source code
def make_whole_point(self, atomlist, point): for atom in atomlist: bestperiodic, key = self.tools.findBestPairPeriodic(fixed_atom=point, periodic_atom=self.at_cart[atom], basis=self.B) self.at_frac[atom] = self.tools.cart_to_frac(self.B, bestperiodic) self.at_cart[atom] = bestperiodic
def read_poscar(*args, **kwargs)
-
Expand source code
def inner1(*args, **kwargs): # storing time before function execution begin = time.time() val = func(*args, **kwargs) # storing time after function execution end = time.time() timer_name = func.__name__ timer_time = end-begin if timer_name in timers_dict: timers_dict[timer_name] += timer_time else: timers_dict[timer_name] = timer_time return val
def recalculate_poscar(*args, **kwargs)
-
Expand source code
def inner1(*args, **kwargs): # storing time before function execution begin = time.time() val = func(*args, **kwargs) # storing time after function execution end = time.time() timer_name = func.__name__ timer_time = end-begin if timer_name in timers_dict: timers_dict[timer_name] += timer_time else: timers_dict[timer_name] = timer_time return val
def rigid_displacement(*args, **kwargs)
-
Expand source code
def inner1(*args, **kwargs): # storing time before function execution begin = time.time() val = func(*args, **kwargs) # storing time after function execution end = time.time() timer_name = func.__name__ timer_time = end-begin if timer_name in timers_dict: timers_dict[timer_name] += timer_time else: timers_dict[timer_name] = timer_time return val
def update_B(*args, **kwargs)
-
Expand source code
def inner1(*args, **kwargs): # storing time before function execution begin = time.time() val = func(*args, **kwargs) # storing time after function execution end = time.time() timer_name = func.__name__ timer_time = end-begin if timer_name in timers_dict: timers_dict[timer_name] += timer_time else: timers_dict[timer_name] = timer_time return val
def write_cart(*args, **kwargs)
-
Expand source code
def inner1(*args, **kwargs): # storing time before function execution begin = time.time() val = func(*args, **kwargs) # storing time after function execution end = time.time() timer_name = func.__name__ timer_time = end-begin if timer_name in timers_dict: timers_dict[timer_name] += timer_time else: timers_dict[timer_name] = timer_time return val
def write_frac(*args, **kwargs)
-
Expand source code
def inner1(*args, **kwargs): # storing time before function execution begin = time.time() val = func(*args, **kwargs) # storing time after function execution end = time.time() timer_name = func.__name__ timer_time = end-begin if timer_name in timers_dict: timers_dict[timer_name] += timer_time else: timers_dict[timer_name] = timer_time return val