6
6
7
7
import numpy as np
8
8
import math
9
+ import ase
10
+ from ase .io import read , write
9
11
10
12
#### Part-0 Dictionaries
11
13
atomic_mass = dict (H = 1.01 , He = 4.00 , Li = 6.94 , Be = 9.01 , B = 10.81 , C = 12.01 ,
33
35
dict_element = {'1' :'H' ,'2' :'He' ,'3' :'Li' ,'4' :'Be' ,'5' :'B' ,'6' :'C' ,'7' :'N' ,'8' :'O' ,'9' :'F' ,'10' :'Ne' ,'11' :'Na' ,'12' :'Mg' ,'13' :'Al' ,'14' :'Si' ,'15' :'P' ,'16' :'S' ,'17' :'Cl' ,'18' :'Ar' ,'19' :'K' ,'20' :'Ca' ,'21' :'Sc' ,'22' :'Ti' ,'23' :'V' ,'24' :'Cr' ,'25' :'Mn' ,'26' :'Fe' ,'27' :'Co' ,'28' :'Ni' ,'29' :'Cu' ,'30' :'Zn' ,'31' :'Ga' ,'32' :'Ge' ,'33' :'As' ,'34' :'Se' ,'35' :'Br' ,'36' :'Kr' ,'37' :'Rb' ,'38' :'Sr' ,'39' :'Y' ,'40' :'Zr' ,'41' :'Nb' ,'42' :'Mo' ,'43' :'Tc' ,'44' :'Ru' ,'45' :'Rh' ,'46' :'Pd' ,'47' :'Ag' ,'48' :'Cd' ,'49' :'In' ,'50' :'Sn' ,'51' :'Sb' ,'52' :'Te' ,'53' :'I' ,'54' :'Xe' ,'55' :'Cs' ,'56' :'Ba' ,'57' :'La' ,'58' :'Ce' ,'59' :'Pr' ,'60' :'Nd' ,'61' :'Pm' ,'62' :'Sm' ,'63' :'Eu' ,'64' :'Gd' ,'65' :'Tb' ,'66' :'Dy' ,'67' :'Ho' ,'68' :'Er' ,'69' :'Tm' ,'70' :'Yb' ,'71' :'Lu' ,'72' :'Hf' ,'73' :'Ta' ,'74' :'W' ,'75' :'Re' ,'76' :'Os' ,'77' :'Ir' ,'78' :'Pt' ,'79' :'Au' ,'80' :'Hg' ,'81' :'Tl' ,'82' :'Pb' ,'83' :'Bi' ,'84' :'Po' ,'85' :'At' ,'86' :'Rn' ,'87' :'Fr' ,'88' :'Ra' ,'89' :'Ac' ,'90' :'Th' ,'91' :'Pa' ,'92' :'U' ,'93' :'Np' ,'94' :'Pu' ,'95' :'Am' ,'96' :'Cm' ,'97' :'Bk' ,'98' :'Cf' ,'99' :'Es' ,'100' :'Fm' ,'101' :'Md' ,'102' :'No' ,'103' :'Lr' ,'104' :'Rf' ,'105' :'Db' ,'106' :'Sg' ,'107' :'Bh' ,'108' :'Hs' ,'109' :'Mt' ,}
34
36
dict_element_2 = {v : k for k , v in dict_element .items ()}
35
37
36
-
37
38
def get_dicts (lines ):
38
39
'''Return a dictionary from POSCAR file '''
39
40
ele_name = str (lines [5 ]).rstrip ().split ()
@@ -63,6 +64,21 @@ def read_car(file_read):
63
64
dict_car1 , dict_car2 = get_dicts (lines )
64
65
return lines , dict_car1 , dict_car2
65
66
67
+ def read_car_ase (file_read ):
68
+ '''Return a dictionary from POSCAR file using ASE'''
69
+ dict_1 = {}
70
+ dict_2 = {}
71
+ model = read (file_read , format = 'vasp' )
72
+ ele_list = model .get_chemical_symbols ()
73
+ ele = list (set (ele_list ))
74
+ for num , i in enumerate (ele ):
75
+ key = i + '-' + str (num + 1 )
76
+ num_i = ele_list .count (i )
77
+ list_i = [atom .index + 1 for atom in model if atom .symbol == i ]
78
+ dict_1 [key ] = num_i
79
+ dict_2 [key ] = list_i
80
+ return model , dict_1 , dict_2
81
+
66
82
def is_direct_or_not (lines ):
67
83
is_direct = True
68
84
is_select = True
@@ -73,37 +89,31 @@ def is_direct_or_not(lines):
73
89
else :
74
90
is_select = False
75
91
# start_num = 8
76
- print ('----------------------------------------------' )
77
- print ( 'Pay Attetion ! There is no TTT in the file! ' )
78
- print ( '---------------------------------------------' )
92
+ print ('-' * 40 )
93
+ print ( 'Warning ! There is no TTT in the file! ' )
94
+ print ('-' * 40 )
79
95
if lines [7 ].strip ()[0 ].upper () == 'C' :
80
96
is_direct = False
81
97
return is_direct , is_select
82
98
83
99
def get_vectors (lines ):
84
100
'''
85
101
Get the lattice vectors to convert the direct to cartesian
86
- '''
87
- # scale = float(lines[1].strip().split()[0])
88
-
89
- ### Not_used_method.
90
- # for i in np.arange(2,5):
91
- # line = [float(i) for i in lines[i].strip().split()]
92
- # a.append(line[0])
93
- # b.append(line[1])
94
- # c.append(line[2])
95
- # vector = np.array([a,b,c])
96
-
102
+ '''
97
103
la1 = np .array ([ float (i ) for i in lines [2 ].strip ().split () ])
98
104
la2 = np .array ([ float (i ) for i in lines [3 ].strip ().split () ])
99
105
la3 = np .array ([ float (i ) for i in lines [4 ].strip ().split () ])
100
106
vector = np .transpose (np .array ([la1 , la2 , la3 ]))
101
-
102
- return vector , la1 , la2
107
+ return vector
108
+
109
+ def get_vectors_ase (model ):
110
+ cell = np .array (model .get_cell ())
111
+ vector = np .transpose (cell )
112
+ return vector
103
113
104
114
def get_abc (lines ):
105
115
'''
106
- Get the lattice vectors to convert the direct to cartesian
116
+ Get the lattice information: length in x, y, and z directions, surface area and volume.
107
117
'''
108
118
scale = float (lines [1 ].strip ().split ()[0 ])
109
119
la1 = np .array ([ float (i ) for i in lines [2 ].strip ().split () ])
@@ -112,22 +122,39 @@ def get_abc(lines):
112
122
a_length = np .linalg .norm (la1 ) * scale
113
123
b_length = np .linalg .norm (la2 ) * scale
114
124
c_length = np .linalg .norm (la3 ) * scale
115
- A = np .cross (la1 , la2 )[- 1 ]
116
- V = np .dot (np .cross (la1 , la2 ), la3 )
125
+ A = np .cross (la1 , la2 )[- 1 ] # Surface area
126
+ V = np .dot (np .cross (la1 , la2 ), la3 ) # Volume
117
127
return a_length , b_length , c_length , A , V
118
128
129
+ def get_abc_ase (model ):
130
+ '''
131
+ Get the lattice information: length in x, y, and z directions, surface area and volume.
132
+ '''
133
+ cell = np .array (model .get_cell ())
134
+ a ,b ,c = model .cell .cellpar ()[:3 ]
135
+ A = np .cross (cell [0 ], cell [1 ])[- 1 ]
136
+ V = model .get_volume ()
137
+ return a , b , c , A , V
138
+
119
139
120
140
def get_coordinate (lines , ele_indice ):
121
141
'''
122
- Get the atom xyz coordinate from the POSCAR which is in cartesian format
142
+ Get the atom xyz coordinate from the POSCAR which must be in cartesian format.
123
143
'''
124
144
ele_indice = int (ele_indice ) + 8
125
145
coordinate = np .array ([float (i ) for i in lines [ele_indice ].strip ().split ()[0 :3 ]])
126
146
return coordinate
127
147
148
+ def get_coordinate_ase (model ,ele_indice ):
149
+ '''
150
+ Get the atom xyz coordinate from the POSCAR which must be in cartesian format.
151
+ '''
152
+ ele_indice = int (ele_indice ) - 1 # ASE counts the index from 0
153
+ coordinate = model .get_positions ()[ele_indice ]
154
+ return coordinate
155
+
128
156
def determinelayers (lines ,threshold = 0.5 ):
129
157
layerscount = {}
130
- # print(lines)
131
158
line_total = sum ([int (i ) for i in lines [6 ].strip ().split ()]) + 8
132
159
z = [float (lines [i ].split ()[2 ]) for i in range (9 , line_total + 1 )]
133
160
seq = sorted (z )
@@ -144,28 +171,6 @@ def determinelayers(lines,threshold=0.5):
144
171
layerscount [i ].append (k + 1 )
145
172
return layerscount
146
173
147
-
148
- #def determinelayers(z_cartesian):
149
- # seq = sorted(z_cartesian)
150
- # min = seq[0]
151
- # layerscount = {}
152
- # sets = [min]
153
- # for j in range(len(seq)):
154
- # if abs(seq[j]-min) >= threshold:
155
- # min = seq[j]
156
- # sets.append(min)
157
- #
158
- # for i in range(1,len(sets)+1):
159
- # layerscount[i] = []
160
- # for k in range(len(z_cartesian)):
161
- # if abs(z_cartesian[k]-sets[i-1]) <= threshold:
162
- # layerscount[i].append(k)
163
- #
164
- # return layerscount
165
-
166
-
167
-
168
-
169
174
def get_angle (u ,v ):
170
175
'''
171
176
Get the angle between two vectors
@@ -201,6 +206,14 @@ def get_distance(lines, a, b):
201
206
202
207
return distance
203
208
209
+
210
+ def get_distance_ase (model , a , b ):
211
+ ''' Get the distance between atom a and b. a and b are counted starting from 1.'''
212
+ atom_A = a - 1
213
+ atom_B = b - 1
214
+ distance = model .get_distance (atom_A , atom_B , mic = True )
215
+ return distance
216
+
204
217
def get_intact_one_atom (lines , A , B ):
205
218
'''atom B is the anchoring point'''
206
219
la1 , la2 = get_vectors (lines )[1 :]
@@ -229,11 +242,12 @@ def get_intact_molecule(lines, atom_list, atom_B):
229
242
return coord_list
230
243
231
244
def get_distance_direct (a ,b ):
232
- '''print the distance '''
245
+ '''print the distance between two coordinates. Here a, and b are coordinates. '''
233
246
vector_ab = a - b
234
247
distance = np .linalg .norm (vector_ab )
235
248
return distance
236
249
250
+
237
251
def get_rotate_infor (lines , raw_infor ):
238
252
'''Along the axis(atom_A, atom_B), rotate atoms by theta angle (in degree).
239
253
Generall Command: rotate.py atom_A atom_B atom_1 atom_2 ... Angle
@@ -355,7 +369,6 @@ def atom_list_append(num):
355
369
if i == k .split ('-' )[0 ]:
356
370
for ele in v :
357
371
atom_list_append (ele )
358
- #print('You select atoms:\t %s' %(atom_list))
359
372
return atom_list
360
373
361
374
atom_selected = []
0 commit comments