Skip to content

Commit

Permalink
Tested for all
Browse files Browse the repository at this point in the history
  • Loading branch information
gasplant64 committed Mar 12, 2021
1 parent 1a48559 commit 14b4c14
Show file tree
Hide file tree
Showing 2 changed files with 252 additions and 42 deletions.
50 changes: 50 additions & 0 deletions test_sf/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,53 @@
pickle1 = test_sf.load_pickle('data1.pickle')
print('Pickled data :',pickle1['x']['Te'][:,131])
### G4 SF validation OK ###


## Use Class to test symmetry function ##

## load data of OUTCAR & yaml & pickled data
load = test_sf.Test_symmetry_function(atom_name = 'OUTCAR_1' , yaml_name = 'input.yaml' , pickled_name = 'data1.pickle')

## Can load data seperatly
#load.set_structure(atoms_name = 'OUTCAR_1')
#load.set_yaml(yaml_name = 'inpuy.yaml')
#load.set_pickled(pickled_name = 'data1.pickle')

## Also load param_XX seperately
#load.set_params(atom = 'Te', params_dir = 'params_Te')

##Read infomation of loaded data
#load.show_pickled_info()
#load.show_atom_info()


## Calculating symmetry function ##

## Calculate symmetry funvtion of : (atom_type , atom_number , line of symmetry function parameters)

cal = load.calculate_sf(atom = 'Te' , number = 4 , line = 122) # 122th symmetry funtion of params_Te (4th atom of Te)
pic = load.get_sf_from_pickle(atom = 'Te' , number = 4 , line = 122) ## Same format

print('Calculated data :',cal)
print('Pickled data :',pic)

# Get all symmetry function of specific atom
cal = load.calculate_sf_atom(atom = 'Te' , number = 7) # Calculate all SF for 7th atom of Te
pic = load.get_sf_from_pickle_atom(atom = 'Te' , number = 7) #same format

print('')
print('Calculated data :',cal)
print('Pickled data :',pic)


# Get value of specific symmetry function of all atom
cal = load.calculate_sf_line(atom = 'Sb' , line = 111) # Calculate 111th SF in param_Sb for all atom of Sb
pic = load.get_sf_from_pickle_line(atom = 'Sb' , line = 111) #same format

print('')
print('Calculated data :',cal)
print('Pickled data :',pic)




244 changes: 202 additions & 42 deletions test_sf/test_sf.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@
import yaml
import numpy as np
import math
from math import pi
from numpy import pi


##Set precision using numpy ##
np.set_printoptions(precision = 8)

##### File processing #####
#load pickle file(tempoaray) at util.__init__
Expand Down Expand Up @@ -70,12 +74,14 @@ def read_yaml(filename):
#Run symmetry functions as input ase.atoms
def _cutoff_func(dist , cutoff):
out = math.cos(pi*dist/cutoff) + 1.0
out = 0.5*float(out)
out = 0.5*np.float64(out)
out = np.float64(out)
return out

#G2 symmetry functions
def _g2_ker(dist ,cutoff,eta , r_s = 0):
out = math.exp(-eta*(dist-r_s)**2)*_cutoff_func(dist , cutoff)
out = np.exp(-eta*(dist-r_s)**2)*_cutoff_func(dist , cutoff)
out = np.float64(out)
return out

#G4 symmetry functions
Expand All @@ -84,12 +90,14 @@ def _g4_ker(dist_ij,dist_ik,dist_jk, cutoff,eta ,zeta ,lamda , angle = False):
else: angle_rad = math.acos((dist_ij**2+dist_ik**2-dist_jk**2)/(2*dist_ij*dist_ik))
out = _g2_ker(dist_ij, cutoff , eta)*_g2_ker(dist_ik, cutoff , eta)*_g2_ker(dist_jk, cutoff , eta)
out *= (1 + lamda * math.cos(angle_rad))**zeta
out = np.float64(out)
return out

#G5 symmetry functions
def _g5_ker(dist_ij,dist_ik, angle ,cutoff,eta ,zeta ,lamda):
out = _g2_ker(dist_ij, cutoff , eta)*_g2_ker(dist_ik, cutoff , eta)
out *= (1 + lamda * math.cos(pi/180.0*angle))**zeta
out = np.float64(out)
return out

#Decorator function / preprocess distance & angle of atomic environemnt needed
Expand All @@ -103,6 +111,7 @@ def sym_func(dist_list):
output = 0
for dist in dist_list:
output += _g2_ker(dist,cutoff,eta)
output = np.float64(output)
return output
elif index == 4:
eta = param_d[1]; zeta = param_d[2] ; lamda = param_d[3]
Expand All @@ -115,6 +124,7 @@ def sym_func(dist_list):
if dist[2] < cutoff: #Cufoff for distance Rjk
output += _g4_ker(dist[0],dist[1],dist[2],cutoff,eta ,zeta ,lamda)
output *= 2.0**(1-zeta)
output = np.float64(output)
return output
elif index == 5:
eta = param_d[1]; zeta = param_d[2] ; lamda = param_d[2]
Expand All @@ -123,9 +133,10 @@ def sym_func(dist_list):
output = 0
# dist = [dist_ij,dist_ik, dist_jk] type
for dist in dist_list:
angle = 180/pi*math.acos((dist[0]**2+dist[1]**2-dist[2]**2)/(2*dist[0]*dist[1]))
angle = 180/pi*np.arccos((dist[0]**2+dist[1]**2-dist[2]**2)/(2*dist[0]*dist[1]))
output += _g5_ker(dist[0],dist[1],angle,cutoff,eta ,zeta ,lamda)
output *= 2.0**(1-zeta)
output = np.float64(output)
return output
return sym_func

Expand Down Expand Up @@ -164,8 +175,10 @@ def get_g2_dist(self, num , index_i = False):
dist_out = dist_list[sym_list == i_name]
try: #remove self atom distance (zero)
dist_out = dist_out[dist_out != 0]
dist_out = np.float64(dist_out)
return dist_out
except:
dist_out = np.float64(dist_out)
return dist_out
else: #retrun all distance with all element
sym_list = self.atom_sym[self.bool_dist[num-1,:]]
Expand All @@ -181,6 +194,7 @@ def _get_tri_dist(self, permut):
if permut != None:
i , j , k = permut
out = [self.atom_dist[i,j] , self.atom_dist[i,k],self.atom_dist[j,k]]
out = np.float64(out)
else:
out = None
return out
Expand Down Expand Up @@ -224,23 +238,163 @@ def get_g4_dist(self, num , index_i , index_j):
dist_out = list()
for permut in permut_list:
dist_out.append(self._get_tri_dist(permut))
#print(permut_list)
return dist_out


#Class that generate list of symmetry function
class Test_sf:
def __init__(self , atoms):
self.atoms = atoms # ase.atoms
self.atom_type = None
self.list_sf = list()

#Calculating sf
def calculate(self):
out = None
class Test_symmetry_function:
def __init__(self , atom_name = None, yaml_name = None, pickled_name = None):
## Open file and make Distance_atoms class
if atom_name != None:
self.structure = open_outcar(atom_name)
self.distance = Distance_atoms(self.structure) # Load Distance_atoms structure
self.atom_type = self.distance.atom_index
self.atom_number = self.distance.atom_num_dict
if yaml_name != None:
self.atom_type , params_dir = get_params_dir(yaml_name)
self.params_dict = dict()
self.symmetry_function_dict = dict()
self.length = dict()
for num , atom in enumerate(self.atom_type):
par_i , par_d = read_params(params_dir[num])
self.params_dict[atom] = [par_i , par_d]
#Generate Symmetry function list from parameters
sf_list = list()
tmp = None # Temporary function
for i , params in enumerate(par_d):
tmp = generate_sf(index = int(par_i[i][0]) , param_d = params)
sf_list.append(tmp)
self.length[atom] = len(sf_list)
self.symmetry_function_dict[atom] = sf_list
if pickled_name != None:
self.pickled = load_pickle(pickled_name)
self.pickled_sf = self.pickled['x']

def set_structure(self , atom_name):
self.structure = open_outcar(atom_name)
self.distance = Distance_atoms(self.structure) # Load Distance_atoms structure
self.atom_type = self.distance.atom_index
self.atom_number = self.distance.atom_num_dict

def set_yaml(self , yaml_name):
self.atom_type , params_dir = get_params_dir(yaml_name)
self.params_dict = dict()
self.symmetry_function_dic = dict()
for num , atom in enumerate(self.atom_type):
par_i , par_d = read_params(params_dir[num])
self.params_dict[atom] = [par_i , par_d]
sf_list = list()
for i , params in enumerate(par_d):
sf_list.append(generate_sf(index = par_i[i][0] , param_d = par_d))
self.symmetry_function_dict[atom] = sf_list

def set_pickled(self, piclked_name):
if pickled_name != None:
self.pickled = load_pickle(pickled_name)
self.pickled_sf = self.pickled['x']

#Setting parameters by hands Need atom_name & param_dir
def set_params(self , atom , params_dir):
#Declariation
self.params_dict = dict()
self.symmetry_function_dic = dict()
sf_list = list()
par_i , par_d = read_params(params_dir[num])
self.params_dict[atom] = [par_i , par_d]
for i , params in enumerate(par_d):
sf_list.append(generate_sf(index = par_i[i][0] , param_d = par_d))
self.symmetry_function_dict[atom] = sf_list

def show_pickled_info(self):
print('Atom type : ',self.pickled_sf.keys())
print('Keys : ' , self.pickled.keys())
for name in ['tot_num', 'atom_idx']:
print('{0} : {1}'.format(name , str(self.pickled[name])))

#Show atom type & number from OUTCAR
def show_atom_info(self):
for name in self.atom_type:
print('Tpye of atom : {0} , Number of atoms : {1}'.format(name,self.atom_number[name]))

def calculate_sf(self , atom , number , line , show = False):
if show: print(number,line)
out = 0
index = 0 # Atom number index
for i in self.atom_type:
if i == atom:
break
index += self.atom_number[i]
par_i = self.params_dict[atom][0][line-1]
par_d = self.params_dict[atom][1][line-1]
if show: print(par_i , par_d)
self.distance.set_cutoff(par_d[0])
if par_i[0] == 2: ## get distance for G2
distance = self.distance.get_g2_dist(num = number+index, index_i = par_i[1])
elif par_i[0] == 4 or par_i[0] == 5: ## get distance for G4 G5
distance = self.distance.get_g4_dist(num = number+index , index_i = par_i[1] , index_j = par_i[2])
#Calculate value from SF dictonary
out = self.symmetry_function_dict[atom][line-1](distance)
return out


#Calculating sf need atom name & atom number
def calculate_sf_atom(self , atom , number):
#Loop for all generated symmetry functions !!
sf_list = list()
value = 0 #SF value
index = 0 # Atom number index
for i in self.atom_type:
if i == atom:
break
index += self.atom_number[i]
for num in range(self.length[atom]):
##Get parameter from dictonary
par_i = self.params_dict[atom][0][num]
par_d = self.params_dict[atom][1][num]
#Set cufoff from params
self.distance.set_cutoff(par_d[0])
if par_i[0] == 2: ## get distance for G2
distance = self.distance.get_g2_dist(num = number+index , index_i = par_i[1])
elif par_i[0] == 4 or par_i[0] == 5: ## get distance for G4 G5
distance = self.distance.get_g4_dist(num = number+index , index_i = par_i[1] , index_j = par_i[2])
#Calculate value from SF dictonary
value = self.symmetry_function_dict[atom][num](distance)
sf_list.append(value)
return np.asarray(sf_list , dtype = np.float64)

def calculate_sf_line(self , atom , line):
sf_list = list()
#Get parameter of SF
par_i = self.params_dict[atom][0][line-1]
par_d = self.params_dict[atom][1][line-1]
self.distance.set_cutoff(par_d[0])
num = 1
for i in self.atom_type:
if i == atom:
break
num += self.atom_number[i]
for i in range(num,num+self.atom_number[atom]):
if par_i[0] == 2: ## get distance for G2
distance = self.distance.get_g2_dist(num = i , index_i = par_i[1])
elif par_i[0] == 4 or par_i[0] == 5: ## get distance for G4 G5
distance = self.distance.get_g4_dist(num = i , index_i = par_i[1] , index_j = par_i[2])
sf_list.append(self.symmetry_function_dict[atom][line-1](distance))
return np.asarray(sf_list , dtype = np.float64)

def get_sf_from_pickle(self,atom, number , line):
out = self.pickled_sf[atom][number-1,line-1]
return out

#Get symmetry function values from pickled file
def get_sf_from_pickle_line(self,atom, line):
out = self.pickled_sf[atom][:,line-1]
return out

#Get symmetry function values from pickled file
def get_sf_from_pickle_atom(self,atom, number):
out = self.pickled_sf[atom][number-1,:]
return out


#testing temporary code
if __name__ == '__main__':
Expand Down Expand Up @@ -301,32 +455,38 @@ def calculate(self):
#dist.get_g4_dist(32,3,3)

### G2 SF Validation ###
cal_list = list()
print('_'*60)
for i in range(33,73):
cal_list.append(test_g2(dist.get_g2_dist(i,1)))
print('Testing G2 symmetry function')
print('Calculated SF :',np.array(cal_list))
pickle1 = load_pickle('data1.pickle')
print('Pickled data :',pickle1['x']['Te'][:,0])
#cal_list = list()
#print('_'*60)
#for i in range(33,73):
# cal_list.append(test_g2(dist.get_g2_dist(i,1)))
#print('Testing G2 symmetry function')
#print('Calculated SF :',np.array(cal_list))
#pickle1 = load_pickle('data1.pickle')
#print('Pickled data :',pickle1['x']['Te'][:,0])
### G2 SF validation OK ###
### G4 SF validation ###
cal_list = list()
print('_'*60)
for i in range(33,73):
cal_list.append(test_g4(dist.get_g4_dist(i,3,3)))
print('Testing G4 symmetry function')
print('Calculated SF :',np.array(cal_list))
pickle1 = load_pickle('data1.pickle')
print('Pickled data :',pickle1['x']['Te'][:,131])
### G4 SF validation not already... (Symmetry function not working)
### G4 SF validation ###
cal_list = list()
print('_'*60)
for i in range(33,73):
cal_list.append(test_g4(dist.get_g4_dist(i,2,3)))
print('Testing G4 symmetry function')
print('Calculated SF :',np.array(cal_list))
pickle1 = load_pickle('data1.pickle')
print('Pickled data :',pickle1['x']['Te'][:,113])
### G4 SF validation not already... (Symmetry function not working)
#### G4 SF validation ###
#cal_list = list()
#print('_'*60)
#for i in range(33,73):
# cal_list.append(test_g4(dist.get_g4_dist(i,3,3)))
#print('Testing G4 symmetry function')
#print('Calculated SF :',np.array(cal_list))
#pickle1 = load_pickle('data1.pickle')
#print('Pickled data :',pickle1['x']['Te'][:,131])
### G4 SF validation OK ###
#### G4 SF validation ###
#cal_list = list()
#print('_'*60)
#for i in range(33,73):
# cal_list.append(test_g4(dist.get_g4_dist(i,2,3)))
#print('Testing G4 symmetry function')
#print('Calculated SF :',np.array(cal_list))
#pickle1 = load_pickle('data1.pickle')
#print('Pickled data :',pickle1['x']['Te'][:,113])
test = Test_symmetry_function(atom_name = 'OUTCAR_1' , yaml_name = 'input.yaml' , pickled_name = 'data1.pickle')
#test.show_pickled_info()
#test.show_atom_info()
print(test.get_sf_from_pickle_atom(atom = 'Te' , number = 1))
#print(test.get_sf_from_pickle_line(atom = 'Sb' , line = 100))
#print(test.calculate_sf_line(atom = 'Sb' , line = 100 ))
print(test.calculate_sf_atom(atom = 'Te' , number = 1 ))

0 comments on commit 14b4c14

Please sign in to comment.