コード例 #1
0
    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()