def load_polarization(self, path): """ This function tries to read Berry phase calculations from three files: filename+'_berry_1' filename+'_berry_2' filename+'_berry_3' If the files are not readable, no polarization attribute is set. On successful run this method fills the following attributes: - self.polarization - polarization as calculated from the three files, in cartesian coordinates (3 e/A**2) - self.ev_phase - expectation value reported by VASP for each of the three directions (3x3 -e*A) - self.ev_recip - the mean of the expectation value projected to internal coordinates (3 -e) - self.berry_phase - berry phases of all strings in each of the directions (3xN 1) - self.polarization_quant - polarization quant for the calculation (3x3 e/A**2) - self.i_polarization_quant - inverse of polarization quant """ self.berry_phase = 3 * [None] self.berry_ev = 3 * [None] self.berry_ion = 3 * [None] self.num_per_type = [] # Noncollinear calculations are officially numspin==1, but they do contain separate electrons, not electron pairs, # Therefore, they should be treated as numspin==2 for calculation of polarizations. self.numspin = 2 # Extract information from OUTCAR file in each of 3 directions. for kdirection in range(1, 4): fname = os.path.join(path, 'Berry_%d/OUTCAR' % kdirection) if os.access(fname, os.R_OK): # open and read OUTCAR file outcar = Outcar(fname) # berry phase outcar.read_pattern( { 'berry_phase': r"Im\s+ln\[Det\|M_k\|\]=\s+([+-]?\d+\.\d+)\s" }, terminate_on_match=False, postprocess=float) bphase = [ item for sublist in outcar.data.get("berry_phase") for item in sublist ] # k-point weights outcar.read_pattern( { 'kpoint_weights': r"K-point string #\s+\S+\s+weight=\s+([+-]?\d+\.\d+)\s" }, terminate_on_match=False, postprocess=float) kpoint_weights = [ item for sublist in outcar.data.get("kpoint_weights") for item in sublist ] self.berry_phase[kdirection - 1] = np.array( [list(x) for x in zip(bphase, kpoint_weights)]) #self.berry_ev[kdirection-1] = self.read_berry_ev(fname) # alternative way to read berry_ev from Outcar self.berry_ev[kdirection - 1] = self.read_berry_ev_old(fname) outcar.read_lcalcpol() else: # Make sure, we have 0,0,0 as polarisation in case there is no berry phase output available print('No file with polarization') self.berry_phase = 3 * [np.zeros((1, 2))] self.berry_ev = 3 * [np.zeros((3))] self.berry_ion = 3 * [[[0., 0., 0.]]] self.polarization_quant = self.unit_cell.copy() / self.volume self.berry_multiplier = 1. self.polarization_quant *= self.berry_multiplier self.i_polarization_quant = np.linalg.inv( self.polarization_quant) self.ev_recip = np.dot(np.mean(self.berry_ev, axis=0), self.recip_cell) self.recalculate_polarization() return self.polarization_quant = self.unit_cell.copy() / self.volume # In case of nonpolarised calculations, we have two electrons per each Berry string # So the quantum needs to be doubled. self.berry_multiplier = 3 - self.numspin self.polarization_quant *= self.berry_multiplier self.i_polarization_quant = np.linalg.inv(self.polarization_quant) self.ev_recip = np.dot(np.mean(self.berry_ev, axis=0), self.recip_cell) self.recalculate_polarization()