Source code for configuration

"""
.. 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