def read_magnetic_moments(poscar=None, outcar='./OUTCAR', orbital=None, symnum=None): poscar = os.path.join(os.path.split(outcar)[0], 'POSCAR') atoms = read(poscar) sdict = symbol_number(atoms) magmoms = np.zeros(len(atoms)) orb_magmoms = [] n = 0 lines = open(outcar, 'r').readlines() for line in lines: if line.rfind('magnetization (x)') > -1: for m in range(len(atoms)): magmoms[m] = float(lines[n + m + 4].strip().split()[-1]) orb_magmoms.append( [float(x) for x in lines[n + m + 4].strip().split()[1:-1]]) n += 1 if orbital is None and symnum is None: return np.array(magmoms) elif orbital is None and symnum is not None: return np.array(magmoms)[sdict[symnum]] elif orbital is not None and symnum is not None: return np.array(orb_magmoms)[sdict[symnum]][orbital] else: return np.array(orb_magmoms)[:, orbital]
def write_all_octahedra_info(atoms,center_symbol_list,vertex_symbol,max_distance,output='octa_info.csv',axis_type=None,x=(1,0,0),y=(0,1,0),z=(0,0,1), var_distance=False): """ write all octahedra info into a file. """ symdict=symbol_number(atoms) myfile=open(output,'w') for symnum in symdict: sym=symnum_to_sym(symnum) print(sym) if sym in center_symbol_list: print(sym) this_oct=get_octahedron(atoms,symnum,vertex_symbol,max_distance,axis_type=axis_type,x=x,y=y,z=z,var_distance=var_distance) avg_rotations=this_oct.get_avg_rotations() bond_lengths=this_oct.get_bond_lengths() avg_bond_length=np.average(bond_lengths) distortion_factor=this_oct.get_distortion() vertex_angles=this_oct.get_vertex_angles(target_symbol_list=center_symbol_list) myfile.write('Info of %s :\n'%symnum) myfile.write("avg_rot: %s\n"%('\t'.join([str(a) for a in avg_rotations]))) myfile.write("avg_bond: %s\n"%avg_bond_length) myfile.write("distrotion factor: %s\n"%distortion_factor) myfile.write("vertex lengths: %s\n"%('\t'.join([str(a) for a in bond_lengths]))) myfile.write("vertex angles: %s\n\n"%('\t'.join([str(a) for a in list(vertex_angles.values())]))) myfile.close()
def even_or_odd_path(atoms,from_symnum,node_sym_list,to_symnum_list=None,first_neighbor_min=2.5,first_neighbor_max=4.5): """ Find whether the distance of the atoms with symnum in to_list to the atom(from_symnum) is even or odd. The distance to the first neighbor is 1. The 1st neighbor's 1st neighbor is 2. etc.... Args: atoms: from_symnum to_sym_list: The symbol of the atoms, eg:['Fe','Ni' ], Note the from_symnum should be start with the symbol in this list to_symnum_list: The symbol_number of the atoms, eg:['Fe1','Fe2','Ni1'].Only one of the to_sym_list and to_symnum_list should should be specified. first_neighbor_min/max: The min/max distance to the first neighbor Returns: a dict. The values are 1/-1. 1 is odd, -1: even eg {'Fe1':1,'Ni1':-1} """ #1. Get the first neighbor list symdict=symbol_number(atoms) symnums=list(symdict.keys()) node_list=[] for s in symnums: #print s if symnum_to_sym(s) in node_sym_list: node_list.append(s) if not from_symnum in node_list: raise Exception('from_symnum should be of one of the nodes') positions=atoms.get_positions() node_positions=[positions[symdict[i]] for i in node_list] from scipy.sparse import csr_matrix N=len(node_list) #dmat=csr_matrix((N,N)) row=[] col=[] val=[] dist=lambda pos1,pos2 :np.linalg.norm(np.asarray(pos1)-np.asarray(pos2)) for i,pi in enumerate(node_positions): for j,pj in enumerate(node_positions): if i==j: row.append(i) col.append(j) val.append(0) else: #print pi,pj #print dist(pi,pj) if first_neighbor_min <dist(pi,pj)<first_neighbor_max: row.append(i) col.append(j) val.append(1) dmat=csr_matrix((val,(row,col)),shape=(N,N)) #print dmat from scipy.sparse.csgraph import dijkstra path_mat=dijkstra(dmat,directed=False,unweighted=True) i_node=node_list.index(from_symnum) def even_odd(x): if int(x)%2==0: return 1 else: return -1 return node_list,[even_odd(x) for x in path_mat[i_node]]
def get_symdict(filename='POSCAR', atoms=None): """ get a symbol_number: index dict. """ if filename is None and atoms is not None: syms = atoms.get_chemical_symbols() elif filename is not None and atoms is None: syms = read(filename).get_chemical_symbols() symdict = symbol_number(syms) return symdict
def find_neighbouring_octahedron(self,direction='upper',target_symbol_list=None,do_force_near_0=False): """ args: direction: the directio of the target to be found. target_symbol_list: the center of the octahdron to be found, should be a tuple. if None, the same as the center of the current octahedron eg. ('Fe','Ti') """ if target_symbol_list is None: target_symbol_list=(self.center.symbol,) else: target_symbol_list=tuple(target_symbol_list) # -> a tuple because .startswith shoulcd be with tuples but lists. pdict={'upper':'lower','left':'right','forward':'backward','lower':'upper','right':'left','backward':'forward'} if do_force_near_0: natoms=force_near_0(self.atoms,max=0.9) else: natoms=self.atoms target=None ratoms=natoms.copy() cell=ratoms.get_cell() ratoms=ratoms.repeat([3,3,3]) ratoms.translate(scaled_pos_to_pos((-1,-1,-1),cell)) rsym_dict=symbol_number(ratoms) for sym_num in rsym_dict: target_center_atom=ratoms[rsym_dict[sym_num]] if sym_num.startswith(target_symbol_list) and distance(self.center,target_center_atom)<=2*self.max_distance: t_octa=octahedra() t_octa.set_axis(x=self.x,y=self.y,z=self.z) try: t_octa.get_octahedra(ratoms,center_atom=ratoms[rsym_dict[sym_num]],atom_symbol=self.vertex_symbol,max_distance=self.max_distance,repeat=False,do_force_near_0=False) #print sym_num, t_octa.number_of_vertexes nm=np.linalg.norm(self.__dict__[direction].position- t_octa.__dict__[pdict[direction]].position) #print nm if nm<0.1: target= t_octa break #print sym_num except Exception: pass #print( 'exception:',exc) """ for sym_num in self.sym_dict: if sym_num.startswith(target_symbol_list): t_octa=octahedra() t_octa.set_axis(x=self.x,y=self.y,z=self.z) try: t_octa.get_octahedra(natoms,center_atom=self.atoms[self.sym_dict[sym_num]],atom_symbol=self.vertex_symbol,max_distance=self.max_distance) #t_octa.read_octahedra(self.filename,center_sym_number=sym_num,vertex_symbol=self.vertex_symbol,max_distance=self.max_distance) if self.__dict__[direction].index == t_octa.__dict__[pdict[direction]].index: target= t_octa #print sym_num except Exception as exc: print exc pass #print( 'exception:',exc) """ if target is None: raise Exception("No neighbour found") else: #print "Found" pass return target