# -*- coding: utf-8 -*-
from __future__ import print_function
"""
.. module:: Common_structures_for_Perovskites.
.. moduleauthor:: Dawei Wang <dwang5@zoho.com>
This module provides the functions for primitive unit cells of perovskites.
"""
import numpy as np
[docs]class Puc:
"""
This module provides basic class for primitive unit cells (PUC) of perovskites and some basic operations on the PUC level
to actuate the distortion specified in the "Distortion" class.
:param symbols: specifies the symbols of atoms in one primitive unit cell.
:param shift_index: an integer vector indicating the shift from the origin. It is used to indiacte the position of this unit cell in the supercell.
"""
def __init__(self, symbols=['A','B','O'],shift_index=[0,0,0]):
self.symbols=symbols
self.atoms = [
{'tag': symbols[0], 'pos': [0.5,0.5,0.5]},
{'tag': symbols[1], 'pos': [0.0,0.0,0.0]},
{'tag': symbols[2], 'pos': [0.5,0.0,0.0]},
{'tag': symbols[2], 'pos': [0.0,0.5,0.0]},
{'tag': symbols[2], 'pos': [0.0,0.0,0.5]}
]
self.shift_index=shift_index
def bravais_basis(self):
#return absolute position
p = list(map(lambda x: np.add(x['pos'],self.shift_index),
self.atoms))
return list(map(lambda x: x.tolist(),p))
def element_basis(self):
#print atoms symbols
return list(map(lambda x: x['tag'], self.atoms))
def rotate_atom(self,atom,omega,covera):
#define the rotation of the oxygen octahedron
if atom['tag']==self.symbols[2]:
pos=atom['pos']
a = np.array(omega)
b = np.array(pos)
pos1 = np.cross(a,b*np.array([1.,1.,covera]))+b
atom['pos'] = pos1.tolist()
return atom
[docs] def rotate(self,omega=[0,0,0],covera=1.0):
"""
Only O atoms are rotated.
:param omega: Rotation angle of oxygen octahedron in **a**-, **b**-, **c**-axis.
:param covera: The ratio of the length of unit cell along **c**-axis to **a**-axis, which indicates a small distortion of the unit cell .
"""
self.atoms = list(
map(lambda x: self.rotate_atom(x,omega,covera), self.atoms)
)
[docs] def shift(self,u=[0,0,0],local_mode=[[0.0,0.0,0.0,0.0,0.0]]):
"""
:param u: Magnitudes of the vibration in **a**-, **b**-, **c**-axis.
:param local_mode: Order is in delta_A, delta_B, delta_O-perp, delta_O-perp, delta_O-parallel
"""
# dumb but effective method.
dA=local_mode[0]
dB=local_mode[1]
dOp=local_mode[2]
dOq=local_mode[4]
# A little math show the following works.
dpq = np.array([
[dA,dA,dA],
[dB,dB,dB],
[dOq,dOp,dOp],
[dOp,dOq,dOp],
[dOp,dOp,dOq]
])
du = np.array([
[u[0],0.,0.],
[0.,u[1],0.],
[0.,0.,u[2]]
])
rslt = np.matmul(dpq,du)
for i in range(5):
self.atoms[i]['pos'] += rslt[i]
#print atoms positions
def print_atoms(self):
list(map(lambda x: print(x), self.atoms))