"""
.. module:: Configuratinos
:synopsis: Framework for constructing charge, dipole configurations.
.. moduleauthor:: D. Wang <dwang5@zoho.com>
"""
import numpy as np
from supercell import Supercell
from netCDF4 import Dataset
import time
from cmath import exp
from math import atan
[docs]class Charge_config(Supercell):
"""
Charge_config inherits from the 'Supercell' class.
Args:
n1,n2,n3 are the number of repeated unitcells along the three directions of the 'lattice'.
lattice specifies the Bravais lattice of a **unit cell**.
"""
def __init__(self, n1, n2, nz, lattice):
Supercell.__init__(self, n1, n2, nz, lattice)
self.alloy_calculated = False
self.signs = np.zeros(self.nsites)
[docs] def write_alloy_matrix(self, fn):
"""
Write the out put to a 'netcdf' file named 'fn'.
"""
if self.alloy_calculated == False:
print("Need to generate the alloy first ...")
exit()
ccpm = Dataset(fn, "w", format="NETCDF4")
ccpm.createDimension("ia", self.nsites)
matrix = ccpm.createVariable('matrix', np.float64, ('ia'))
ccpm.description = 'Alloy matrix'
ccpm.history = 'Created at ' + time.ctime(time.time())
matrix[:] = self.signs
ccpm.close()
[docs] def generate_high_symmetry(self, p=1, k=(0, 0, 0)):
"""
The distribution of charge is set according to this k value and the
charge magnitude.
:param p: represents the magnitude of charge.
:param k: k = (kx,ky,kz): represents the high symmetry points in the reciprocal space.
"""
pi = 4.0 * atan(1.0)
for l in range(self.nsites):
ixa = self.ixa[l]
iya = self.iya[l]
iza = self.iza[l]
# This is a little redundant, but may be useful in the future.
dum = exp(1j * pi * (k[0] * ixa + k[1] * iya + k[2] * iza))
self.signs[l] = p * dum.real
self.alloy_calculated = True
[docs]class Dipole_config(Supercell):
"""
Similar to 'Charge config'.
"""
def __init__(self, n1, n2, nz, lattice):
Supercell.__init__(self, n1, n2, nz, lattice)
self.alloy_calculated = False
self.signs = np.zeros((self.nsites, 3))
def write_alloy_matrix(self, fn):
if self.alloy_calculated == False:
print("Need to generate the alloy first ...")
exit()
dipm = Dataset(fn, "w", format="NETCDF4")
direction = dipm.createDimension("direction", 3)
ia = dipm.createDimension("ia", self.nsites)
directions = dipm.createVariable("direction", np.int32, ("direction"))
ias = dipm.createVariable("ia", np.int32, ("ia"))
# The actual 2-d varable.
matrix = dipm.createVariable('matrix', np.float64, ('ia', 'direction'))
dipm.description = 'Alloy matrix'
dipm.history = 'Created at ' + time.ctime(time.time())
matrix[:, :] = self.signs
dipm.close()
[docs] def generate_high_symmetry(self, p=(1, 1, 1), k_px=(0, 0, 0), k_py=(0, 0, 0), k_pz=(0, 0, 0)):
"""
:param p: p=(px,py,pz) represents the magnitude of dpoles.
:param k_px: k_px = (kx,ky,kz) represents a high symmetry points in the reciprocal space and specifies how the value of px on each site.
:param k_py: Similar to k_px.
:param k_pz: Similar to k_px.
"""
pi = 4.0 * atan(1.0)
px = p[0]
py = p[1]
pz = p[2]
for l in range(self.nsites):
ixa = self.ixa[l]
iya = self.iya[l]
iza = self.iza[l]
# This is a little redundant, but may be useful in the future.
dum = exp(1j * pi * (k_px[0] * ixa + k_px[1] * iya + k_px[2] * iza))
self.signs[l, 0] = px * dum.real
dum = exp(1j * pi * (k_py[0] * ixa + k_py[1] * iya + k_py[2] * iza))
self.signs[l, 1] = py * dum.real
dum = exp(1j * pi * (k_pz[0] * ixa + k_pz[1] * iya + k_pz[2] * iza))
self.signs[l, 2] = pz * dum.real
self.alloy_calculated = True