Esempio n. 1
0
    def get_effective_volume_ratio(self, atom_index):
        """Effective volume to free volume ratio.

        After: Tkatchenko and Scheffler PRL 102 (2009) 073005, eq. (7)
        """
        atoms = self.atoms
        finegd = self.calculator.density.finegd

        den_sg, gd = self.calculator.density.get_all_electron_density(atoms)
        den_g = den_sg.sum(axis=0)
        assert (gd == finegd)
        denfree_g, gd = self.hdensity.get_density([atom_index])
        assert (gd == finegd)

        # the atoms r^3 grid
        position = self.atoms[atom_index].position / Bohr
        r_vg, r2_g = coordinates(finegd, origin=position)
        r3_g = r2_g * np.sqrt(r2_g)

        weight_g = denfree_g * self.invweight_g

        nom = finegd.integrate(r3_g * den_g * weight_g)
        denom = finegd.integrate(r3_g * denfree_g)

        return nom / denom
    def get_effective_volume_ratio(self, atom_index):
        """Effective volume to free volume ratio.

        After: Tkatchenko and Scheffler PRL 102 (2009) 073005, eq. (7)
        """
        atoms = self.atoms
        finegd = self.calculator.density.finegd

        den_sg, gd = self.calculator.density.get_all_electron_density(atoms)
        den_g = den_sg.sum(axis=0)
        assert gd == finegd
        denfree_g, gd = self.hdensity.get_density([atom_index])
        assert gd == finegd

        # the atoms r^3 grid
        position = self.atoms[atom_index].position / Bohr
        r_vg, r2_g = coordinates(finegd, origin=position)
        r3_g = r2_g * np.sqrt(r2_g)

        weight_g = denfree_g * self.invweight_g

        nom = finegd.integrate(r3_g * den_g * weight_g)
        denom = finegd.integrate(r3_g * denfree_g)

        return nom / denom
Esempio n. 3
0
 def __init__(self, gd, a=19., center=None):
     self.gd = gd
     self.xyz, self.r2 = coordinates(gd, center)
     self.r = np.sqrt(self.r2)
     self.set_width(a)
     self.exp_ar2 = exp(-self.a * self.r2) 
     self.erf_sar = erf(sqrt(self.a) * self.r)
Esempio n. 4
0
 def __init__(self, gd, a=19., center=None):
     self.gd = gd
     self.xyz, self.r2 = coordinates(gd, center)
     self.r = np.sqrt(self.r2)
     self.set_width(a)
     self.exp_ar2 = exp(-self.a * self.r2)
     self.erf_sar = erf(sqrt(self.a) * self.r)
Esempio n. 5
0
def wignerseitz(gd, atoms, scale=None):
    """Determine which atom is closest to each grid point.

    The atom distances might be scaled by the scale list."""
    if scale is None:
        scale = [1.] * len(atoms)
    else:
        assert(len(scale) == len(atoms))
    r_vG, R2min_G = coordinates(gd, atoms[0].position / Bohr)
    R2min_G *= scale[0]**2
    index_G = gd.zeros(dtype=int)
    for a, atom in enumerate(atoms[1:]):
        r_vG, r2_G = coordinates(gd, atom.position / Bohr)
        r2_G *= scale[a + 1]**2
        index_G = np.where(R2min_G > r2_G, a + 1, index_G)
        R2min_G = np.where(R2min_G > r2_G, r2_G, R2min_G)
    return index_G
Esempio n. 6
0
def wignerseitz(gd, atoms, scale=None):
    """Determine which atom is closest to each grid point.

    The atom distances might be scaled by the scale list."""
    if scale is None:
        scale = [1.] * len(atoms)
    else:
        assert(len(scale) == len(atoms))
    r_vG, R2min_G = coordinates(gd, atoms[0].position / Bohr)
    R2min_G *= scale[0]**2
    index_G = gd.zeros(dtype=int)
    for a, atom in enumerate(atoms[1:]):
        r_vG, r2_G = coordinates(gd, atom.position / Bohr)
        r2_G *= scale[a + 1]**2
        index_G = np.where(R2min_G > r2_G, a + 1, index_G)
        R2min_G = np.where(R2min_G > r2_G, r2_G, R2min_G)
    return index_G
    def initialize(self):
        """Initialize grids."""

        center = self.center
        Rmax = self.Rmax
        dR = self.dR
        gd = self.gd

        # initialize the ylm and Radial grids

        # self.V_R will contain the volume of the R shell
        # self.R_g will contain the radial indicees corresponding to
        #     each grid point
        # self.ball_g will contain the mask of the ball of radius Rmax
        # self.y_Lg will contain the YL values corresponding to
        #     each grid point
        V_R = np.empty((int(Rmax / dR + 1),))
        R_R = np.empty((int(Rmax / dR + 1),))

        r_cg, r2_g = coordinates(gd, self.center, tiny=1.e-78)
        r_g = np.sqrt(r2_g)
        rhat_cg = r_cg / r_g

        ball_g = np.where(r_g < Rmax, 1, 0)
        self.R_g = np.where(r_g < Rmax, r_g / dR, -1).astype(int)

        if hasattr(self, 'L_l'):  # ExpandYl
            npY = np.vectorize(Y, (float,), 'spherical harmonic')
            nL = len(self.L_l)
            y_Lg = []
            for L in range(nL):
                y_Lg.append(npY(L, rhat_cg[0], rhat_cg[1], rhat_cg[2]))
            self.y_Lg = y_Lg

        for i, v in enumerate(V_R):
            R_g = np.where(self.R_g == i, 1., 0.)
            V_R[i] = gd.integrate(R_g)
            R_R[i] = gd.integrate(R_g * r_g)

        self.ball_g = ball_g
        self.V_R = V_R
        self.nominalR_R = self.dR * (np.arange(len(self.V_R)) + .5)
        V_R = np.where(V_R > 0, V_R, -1)
        self.R_R = np.where(V_R > 0, R_R / V_R, self.nominalR_R)
Esempio n. 8
0
    def initialize(self):
        """Initialize grids."""

        center = self.center
        Rmax = self.Rmax
        dR = self.dR
        gd = self.gd

        # initialize the ylm and Radial grids

        # self.V_R will contain the volume of the R shell
        # self.R_g will contain the radial indicees corresponding to
        #     each grid point
        # self.ball_g will contain the mask of the ball of radius Rmax
        # self.y_Lg will contain the YL values corresponding to
        #     each grid point
        V_R = np.empty((int(Rmax / dR + 1), ))
        R_R = np.empty((int(Rmax / dR + 1), ))

        r_cg, r2_g = coordinates(gd, self.center, tiny=1.e-78)
        r_g = np.sqrt(r2_g)
        rhat_cg = r_cg / r_g

        ball_g = np.where(r_g < Rmax, 1, 0)
        self.R_g = np.where(r_g < Rmax, r_g / dR, -1).astype(int)

        if hasattr(self, 'L_l'):  # ExpandYl
            npY = np.vectorize(Y, (float, ), 'spherical harmonic')
            nL = len(self.L_l)
            y_Lg = []
            for L in range(nL):
                y_Lg.append(npY(L, rhat_cg[0], rhat_cg[1], rhat_cg[2]))
            self.y_Lg = y_Lg

        for i, v in enumerate(V_R):
            R_g = np.where(self.R_g == i, 1., 0.)
            V_R[i] = gd.integrate(R_g)
            R_R[i] = gd.integrate(R_g * r_g)

        self.ball_g = ball_g
        self.V_R = V_R
        self.nominalR_R = self.dR * (np.arange(len(self.V_R)) + .5)
        V_R = np.where(V_R > 0, V_R, -1)
        self.R_R = np.where(V_R > 0, R_R / V_R, self.nominalR_R)
Esempio n. 9
0
    def initialize(self, gd):
        """Initialize Y_L arrays"""

        self.gd = gd

        r_cg, r2_g = coordinates(gd, self.center, tiny=1.e-78)
        r_g = np.sqrt(r2_g)
        rhat_cg = r_cg / r_g

        self.l_L = []
        self.y_Lg = []
        npY = np.vectorize(Y, (float, ), 'spherical harmonic')
        L = 0
        for l in range(self.lmax + 1):
            for m in range(2 * l + 1):
                self.y_Lg.append(
                    np.sqrt(4 * np.pi / (2 * l + 1)) * r_g**l *
                    npY(L, rhat_cg[0], rhat_cg[1], rhat_cg[2]))
                self.l_L.append(l)
                L += 1
    def initialize(self, gd):
        """Initialize Y_L arrays"""

        self.gd = gd

        r_cg, r2_g = coordinates(gd, self.center, tiny=1.e-78)
        r_g = np.sqrt(r2_g)
        rhat_cg = r_cg / r_g

        self.l_L = []
        self.y_Lg = []
        npY = np.vectorize(Y, (float,), 'spherical harmonic')
        L = 0
        for l in range(self.lmax + 1):
            for m in range(2 * l + 1):
                self.y_Lg.append(
                    np.sqrt(4 * np.pi / (2 * l + 1)) * r_g ** l *
                    npY(L, rhat_cg[0], rhat_cg[1], rhat_cg[2])
                )
                self.l_L.append(l)
                L += 1
Esempio n. 11
0
    def initialize(self):
        """Initialize grids."""
        
        center = self.center
        Rmax = self.Rmax
        dR = self.dR
        gd = self.gd
        nL = len(self.L_l)

        # initialize the ylm and Radial grids

        # self.V_R will contain the volume of the R shell
        # self.R_g will contain the radial indicees corresponding to
        #     each grid point
        # self.ball_g will contain the mask of the ball of radius Rmax
        # self.y_Lg will contain the YL values corresponding to
        #     each grid point
        V_R = np.zeros((int(Rmax / dR + 1),))
        npY = np.vectorize(Y, (float,), 'spherical harmonic')

        r_cg, r2_g = coordinates(gd, self.center, tiny=1.e-78)
        r_g = np.sqrt(r2_g)
        rhat_cg = r_cg / r_g

        ball_g = np.where(r_g < Rmax, 1, 0)
        R_g = np.where(r_g < Rmax, r_g / dR, -1).astype(int)
        y_Lg = []
        for L in range(nL):
            y_Lg.append(npY(L, rhat_cg[0], rhat_cg[1], rhat_cg[2]))

        for i, v in enumerate(V_R):
            V_R[i] = np.where(R_g == i, 1, 0).sum()
        gd.comm.sum(V_R)

        self.R_g = R_g
        self.ball_g = ball_g
        self.V_R = V_R * gd.dv
        self.y_Lg = y_Lg
Esempio n. 12
0
    def initialize(self):
        """Initialize grids."""

        center = self.center
        Rmax = self.Rmax
        dR = self.dR
        gd = self.gd
        nL = len(self.L_l)

        # initialize the ylm and Radial grids

        # self.V_R will contain the volume of the R shell
        # self.R_g will contain the radial indicees corresponding to
        #     each grid point
        # self.ball_g will contain the mask of the ball of radius Rmax
        # self.y_Lg will contain the YL values corresponding to
        #     each grid point
        V_R = np.zeros((int(Rmax / dR + 1), ))
        npY = np.vectorize(Y, (float, ), 'spherical harmonic')

        r_cg, r2_g = coordinates(gd, self.center, tiny=1.e-78)
        r_g = np.sqrt(r2_g)
        rhat_cg = r_cg / r_g

        ball_g = np.where(r_g < Rmax, 1, 0)
        R_g = np.where(r_g < Rmax, r_g / dR, -1).astype(int)
        y_Lg = []
        for L in range(nL):
            y_Lg.append(npY(L, rhat_cg[0], rhat_cg[1], rhat_cg[2]))

        for i, v in enumerate(V_R):
            V_R[i] = np.where(R_g == i, 1, 0).sum()
        gd.comm.sum(V_R)

        self.R_g = R_g
        self.ball_g = ball_g
        self.V_R = V_R * gd.dv
        self.y_Lg = y_Lg
Esempio n. 13
0
    def get_effective_volume_ratio(self, atom_index):
        """Effective volume to free volume ratio.

        After: Tkatchenko and Scheffler PRL 102 (2009) 073005
        """
        atoms = self.atoms
        finegd = self.gd

        den_g, gd = self.calculator.density.get_all_electron_density(atoms)
        assert(gd == finegd)
        denfree_g, gd = self.hdensity.get_density([atom_index])
        assert(gd == finegd)

        # the atoms r^3 grid
        position = self.atoms[atom_index].position / Bohr
        r_vg, r2_g = coordinates(finegd, origin=position)
        r3_g = r2_g * np.sqrt(r2_g)

        weight_g = np.where(self.atom_index == atom_index, 1.0, 0.0)

        nom = finegd.integrate(r3_g * den_g[0] * weight_g)
        denom = finegd.integrate(r3_g * denfree_g)

        return nom / denom
Esempio n. 14
0
    def calculate(self):
        # Check that kss_list is up-to-date
        if not self.kss_list_ready:
            self.update_list()
            self.kss_prop_ready = False

        # Check if we already have properties for all singles
        if self.kss_prop_ready:
            return
        self.kss_prop_ready = True
        for kss_ip in self.kss_list:
            if kss_ip.dip_mom_r is None or kss_ip.magn_mom is None:
                self.kss_prop_ready = False
                break
        # If had, done
        if self.kss_prop_ready:
            return

        #self.timer.start('Calculate KS properties')

        # Init pair densities
        dnt_Gip = self.calc.wfs.gd.empty()
        dnt_gip = self.calc.density.finegd.empty()
        drhot_gip = self.calc.density.finegd.empty()

        # Init gradients of wfs
        grad_psit2_G = [
            self.calc.wfs.gd.empty(),
            self.calc.wfs.gd.empty(),
            self.calc.wfs.gd.empty()
        ]

        # Init gradient operators
        grad = []
        dtype = pick(self.calc.wfs.kpt_u[self.kpt_ind].psit_nG, 0).dtype
        for c in range(3):
            grad.append(Gradient(self.calc.wfs.gd, c, dtype=dtype, n=2))

        # Coordinate vector r
        R0 = 0.5 * np.diag(self.calc.wfs.gd.cell_cv)
        # R0 = np.array([0.0,0.0,0.0]) # old_version
        #print 'R0', R0
        r_cG, r2_G = coordinates(self.calc.wfs.gd, origin=R0)
        r_cg, r2_g = coordinates(self.calc.density.finegd, origin=R0)

        # Loop over all KS single excitations
        #
        # Transition dipole moment, mu_ip = <p| (-e r) |i>
        # Magnetic transition dipole, m_ip = -(1/2c) <i|L|p>
        # For total m_0I = -m_I0 = -(m_0I)^*, but not for m_ip (right?)
        # R_0I = Im[mu_0I * m_0I]
        # mu_ip^0I =  omega_0I^(-1/2) D_ip      S^(-1/2) F_0I
        # m_ip^0I  = -omega_0I^(+1/2) M_ip C^-1 S^(+1/2) F_0I
        #
        # S_ip,ip = - (eps_p - eps_i) / (n_p - n_i)    (note: n_p < n_i)
        # C_ip,ip = 1 / (n_p - n_i)
        #
        # See:
        # WIREs Comput Mol Sci 2012, 2: 150-166 doi: 10.1002/wcms.55
        # J. Chem. Phys., Vol. 116, 6930 (2002)
        for kss_ip in self.kss_list:
            # If have dipole moment and magnetic moment, already done and skip
            if (kss_ip.dip_mom_r is not None and kss_ip.magn_mom is not None):
                continue

            # Transition dipole moment, mu_ip = <p| (-r) |i>
            kss_ip.calculate_pair_density(dnt_Gip, dnt_gip, drhot_gip)
            #kss_ip.dip_mom_r = self.calc.density.finegd.calculate_dipole_moment(drhot_gip)
            #kss_ip.dip_mom_r = self.calc.density.finegd.calculate_dipole_moment(drhot_gip)
            kss_ip.dip_mom_r = np.zeros(3)
            kss_ip.dip_mom_r[0] = -self.calc.density.finegd.integrate(
                r_cg[0] * drhot_gip)
            kss_ip.dip_mom_r[1] = -self.calc.density.finegd.integrate(
                r_cg[1] * drhot_gip)
            kss_ip.dip_mom_r[2] = -self.calc.density.finegd.integrate(
                r_cg[2] * drhot_gip)

            # Magnetic transition dipole, m_ip = -(1/2c) <i|L|p> = i/2c <i|r x p|p>
            # see Autschbach et al., J. Chem. Phys., 116, 6930 (2002)

            # Gradients
            for c in range(3):
                grad[c].apply(kss_ip.pair_density.psit2_G, grad_psit2_G[c],
                              self.calc.wfs.kpt_u[self.kpt_ind].phase_cd)

            # <psi1|r x grad|psi2>
            #    i  j  k
            #    x  y  z   = (y pz - z py)i + (z px - x pz)j + (x py - y px)
            #    px py pz
            rxnabla_g = np.zeros(3)
            rxnabla_g[0] = self.calc.wfs.gd.integrate(
                kss_ip.pair_density.psit1_G *
                (r_cG[1] * grad_psit2_G[2] - r_cG[2] * grad_psit2_G[1]))
            rxnabla_g[1] = self.calc.wfs.gd.integrate(
                kss_ip.pair_density.psit1_G *
                (r_cG[2] * grad_psit2_G[0] - r_cG[0] * grad_psit2_G[2]))
            rxnabla_g[2] = self.calc.wfs.gd.integrate(
                kss_ip.pair_density.psit1_G *
                (r_cG[0] * grad_psit2_G[1] - r_cG[1] * grad_psit2_G[0]))

            # augmentation contributions to magnetic moment
            # <psi1| r x nabla |psi2> = <psi1| (r-Ra+Ra) x nabla |psi2>
            #                         = <psi1| (r-Ra) x nabla |psi2> + Ra x <psi1| nabla |psi2>
            rxnabla_a = np.zeros(3)
            # <psi1| (r-Ra) x nabla |psi2>
            for a, P_ni in self.calc.wfs.kpt_u[self.kpt_ind].P_ani.items():
                Pi_i = P_ni[kss_ip.occ_ind]
                Pp_i = P_ni[kss_ip.unocc_ind]
                rxnabla_iiv = self.calc.wfs.setups[a].rxnabla_iiv
                for c in range(3):
                    for i1, Pi in enumerate(Pi_i):
                        for i2, Pp in enumerate(Pp_i):
                            rxnabla_a[c] += Pi * Pp * rxnabla_iiv[i1, i2, c]

            self.calc.wfs.gd.comm.sum(rxnabla_a)  # sum up from different procs

            # Ra x <psi1| nabla |psi2>
            Rxnabla_a = np.zeros(3)
            for a, P_ni in self.calc.wfs.kpt_u[self.kpt_ind].P_ani.items():
                Pi_i = P_ni[kss_ip.occ_ind]
                Pp_i = P_ni[kss_ip.unocc_ind]
                nabla_iiv = self.calc.wfs.setups[a].nabla_iiv
                Ra = (self.calc.atoms[a].position / ase.units.Bohr) - R0
                for i1, Pi in enumerate(Pi_i):
                    for i2, Pp in enumerate(Pp_i):
                        # (y pz - z py)i + (z px - x pz)j + (x py - y px)k
                        Rxnabla_a[0] += Pi * Pp * (
                            Ra[1] * nabla_iiv[i1, i2, 2] -
                            Ra[2] * nabla_iiv[i1, i2, 1])
                        Rxnabla_a[1] += Pi * Pp * (
                            Ra[2] * nabla_iiv[i1, i2, 0] -
                            Ra[0] * nabla_iiv[i1, i2, 2])
                        Rxnabla_a[2] += Pi * Pp * (
                            Ra[0] * nabla_iiv[i1, i2, 1] -
                            Ra[1] * nabla_iiv[i1, i2, 0])

            self.calc.wfs.gd.comm.sum(Rxnabla_a)  # sum up from different procs

            #print (kss_ip.occ_ind, kss_ip.unocc_ind), kss_ip.dip_mom_r, rxnabla_g, rxnabla_a, Rxnabla_a

            # m_ip = -1/2c <i|r x p|p> = i/2c <i|r x nabla|p>
            # just imaginary part!!!
            kss_ip.magn_mom = ase.units.alpha / 2. * (rxnabla_g + rxnabla_a +
                                                      Rxnabla_a)

        # Wait... to avoid io problems, and write KS_singles file
        self.lr_comms.parent_comm.barrier()
        if self.lr_comms.parent_comm.rank == 0:
            self.kss_file = open(self.basefilename + '.KS_singles', 'w')
            for kss_ip in self.kss_list:
                format = '%08d %08d  %18.12lf %18.12lf  '
                format += '%18.12lf %18.12lf %18.12lf '
                format += '%18.12lf %18.12lf %18.12lf\n'
                self.kss_file.write(
                    format %
                    (kss_ip.occ_ind, kss_ip.unocc_ind, kss_ip.energy_diff,
                     kss_ip.pop_diff, kss_ip.dip_mom_r[0], kss_ip.dip_mom_r[1],
                     kss_ip.dip_mom_r[2], kss_ip.magn_mom[0],
                     kss_ip.magn_mom[1], kss_ip.magn_mom[2]))
            self.kss_file.close()
        self.lr_comms.parent_comm.barrier()

        self.kss_prop_ready = True  # avoid repeated work
Esempio n. 15
0
from gpaw.poisson import PoissonSolver


def norm(a):
    return np.sqrt(np.sum(a.ravel()**2)) / len(a.ravel())


# Initialize classes
a = 20  # Size of cell
N = 48  # Number of grid points
Nc = (N, N, N)  # Number of grid points along each axis
gd = GridDescriptor(Nc, (a, a, a), 0)  # Grid-descriptor object
solver = PoissonSolver(nn=3)  # Numerical poisson solver
solver.set_grid_descriptor(gd)
solve = solver.solve
xyz, r2 = coordinates(gd)  # Matrix with the square of the radial coordinate
print(r2.shape)
r = np.sqrt(r2)  # Matrix with the values of the radial coordinate
nH = np.exp(-2 * r) / pi  # Density of the hydrogen atom
gauss = Gaussian(gd)  # An instance of Gaussian

# /------------------------------------------------\
# | Check if Gaussian densities are made correctly |
# \------------------------------------------------/
for gL in range(2, 9):
    g = gauss.get_gauss(gL)  # a gaussian of gL'th order
    print('\nGaussian of order', gL)
    for mL in range(9):
        m = gauss.get_moment(g, mL)  # the mL'th moment of g
        print('  %s\'th moment = %2.6f' % (mL, m))
        equal(m, gL == mL, 1e-4)
Esempio n. 16
0
    def __init__(self,
                 iidx=None,
                 jidx=None,
                 pspin=None,
                 kpt=None,
                 paw=None,
                 string=None,
                 fijscale=1,
                 dtype=float):

        if string is not None:
            self.fromstring(string, dtype)
            return None

        # normal entry

        PairDensity.__init__(self, paw)
        PairDensity.initialize(self, kpt, iidx, jidx)

        self.pspin = pspin

        self.energy = 0.0
        self.fij = 0.0

        self.me = np.zeros((3), dtype=dtype)
        self.mur = np.zeros((3), dtype=dtype)
        self.muv = np.zeros((3), dtype=dtype)
        self.magn = np.zeros((3), dtype=dtype)

        self.kpt_comm = paw.wfs.kd.comm

        # leave empty if not my kpt
        if kpt is None:
            return

        wfs = paw.wfs
        gd = wfs.gd

        self.energy = kpt.eps_n[jidx] - kpt.eps_n[iidx]
        self.fij = (kpt.f_n[iidx] - kpt.f_n[jidx]) * fijscale

        # calculate matrix elements -----------

        # length form ..........................

        # course grid contribution
        # <i|r|j> is the negative of the dipole moment (because of negative
        # e- charge)
        me = -gd.calculate_dipole_moment(self.get())

        # augmentation contributions
        ma = np.zeros(me.shape, dtype=dtype)
        pos_av = paw.atoms.get_positions() / Bohr
        for a, P_ni in kpt.P_ani.items():
            Ra = pos_av[a]
            Pi_i = P_ni[self.i].conj()
            Pj_i = P_ni[self.j]
            Delta_pL = wfs.setups[a].Delta_pL
            ni = len(Pi_i)
            ma0 = 0
            ma1 = np.zeros(me.shape, dtype=me.dtype)
            for i in range(ni):
                for j in range(ni):
                    pij = Pi_i[i] * Pj_i[j]
                    ij = packed_index(i, j, ni)
                    # L=0 term
                    ma0 += Delta_pL[ij, 0] * pij
                    # L=1 terms
                    if wfs.setups[a].lmax >= 1:
                        # see spherical_harmonics.py for
                        # L=1:y L=2:z; L=3:x
                        ma1 += np.array([
                            Delta_pL[ij, 3], Delta_pL[ij, 1], Delta_pL[ij, 2]
                        ]) * pij
            ma += sqrt(4 * pi / 3) * ma1 + Ra * sqrt(4 * pi) * ma0
        gd.comm.sum(ma)

        self.me = sqrt(self.energy * self.fij) * (me + ma)
        self.mur = -(me + ma)

        # velocity form .............................

        if self.lcao:
            # XXX Velocity form not supported in LCAO
            return

        me = np.zeros(self.mur.shape, dtype=dtype)

        # get derivatives
        dtype = self.wfj.dtype
        dwfj_cg = gd.empty((3), dtype=dtype)
        if not hasattr(gd, 'ddr'):
            gd.ddr = [Gradient(gd, c, dtype=dtype).apply for c in range(3)]
        for c in range(3):
            gd.ddr[c](self.wfj, dwfj_cg[c], kpt.phase_cd)
            me[c] = gd.integrate(self.wfi.conj() * dwfj_cg[c])

        if 0:
            me2 = np.zeros(self.mur.shape)
            for c in range(3):
                gd.ddr[c](self.wfi, dwfj_cg[c], kpt.phase_cd)
                me2[c] = gd.integrate(self.wfj * dwfj_cg[c])
            print(me, -me2, me2 + me)

        # augmentation contributions
        ma = np.zeros(me.shape, dtype=me.dtype)
        for a, P_ni in kpt.P_ani.items():
            Pi_i = P_ni[self.i].conj()
            Pj_i = P_ni[self.j]
            nabla_iiv = paw.wfs.setups[a].nabla_iiv
            for c in range(3):
                for i1, Pi in enumerate(Pi_i):
                    for i2, Pj in enumerate(Pj_i):
                        ma[c] += Pi * Pj * nabla_iiv[i1, i2, c]
        gd.comm.sum(ma)

        self.muv = -(me + ma) / self.energy

        # magnetic transition dipole ................

        r_cg, r2_g = coordinates(gd)
        magn = np.zeros(me.shape, dtype=dtype)

        wfi_g = self.wfi.conj()
        for ci in range(3):
            cj = (ci + 1) % 3
            ck = (ci + 2) % 3
            magn[ci] = gd.integrate(wfi_g * r_cg[cj] * dwfj_cg[ck] -
                                    wfi_g * r_cg[ck] * dwfj_cg[cj])
        # augmentation contributions
        ma = np.zeros(magn.shape, dtype=magn.dtype)
        for a, P_ni in kpt.P_ani.items():
            Pi_i = P_ni[self.i].conj()
            Pj_i = P_ni[self.j]
            rnabla_iiv = paw.wfs.setups[a].rnabla_iiv
            for c in range(3):
                for i1, Pi in enumerate(Pi_i):
                    for i2, Pj in enumerate(Pj_i):
                        ma[c] += Pi * Pj * rnabla_iiv[i1, i2, c]
        gd.comm.sum(ma)

        self.magn = -alpha / 2. * (magn + ma)

def norm(a):
    return np.sqrt(np.sum(a.ravel() ** 2)) / len(a.ravel())


# Initialize classes
a = 20  # Size of cell
N = 48  # Number of grid points
Nc = (N, N, N)  # Number of grid points along each axis
gd = GridDescriptor(Nc, (a, a, a), 0)  # Grid-descriptor object
solver = PoissonSolver(nn=3)  # Numerical poisson solver
solver.set_grid_descriptor(gd)
solver.initialize()
solve = solver.solve
xyz, r2 = coordinates(gd)  # Matrix with the square of the radial coordinate
print(r2.shape)
r = np.sqrt(r2)  # Matrix with the values of the radial coordinate
nH = np.exp(-2 * r) / pi  # Density of the hydrogen atom
gauss = Gaussian(gd)  # An instance of Gaussian

# /------------------------------------------------\
# | Check if Gaussian densities are made correctly |
# \------------------------------------------------/
for gL in range(2, 9):
    g = gauss.get_gauss(gL)  # a gaussian of gL'th order
    print("\nGaussian of order", gL)
    for mL in range(9):
        m = gauss.get_moment(g, mL)  # the mL'th moment of g
        print("  %s'th moment = %2.6f" % (mL, m))
        equal(m, gL == mL, 1e-4)
Esempio n. 18
0
    def __init__(self, iidx=None, jidx=None, pspin=None, kpt=None,
                 paw=None, string=None, fijscale=1):
        
        if string is not None: 
            self.fromstring(string)
            return None

        # normal entry
        
        PairDensity.__init__(self, paw)
        wfs = paw.wfs
        PairDensity.initialize(self, kpt, iidx, jidx)

        self.pspin=pspin
        
        f = kpt.f_n
        self.fij = (f[iidx] - f[jidx]) * fijscale
        e = kpt.eps_n
        self.energy = e[jidx] - e[iidx]

        # calculate matrix elements -----------

        gd = wfs.gd
        self.gd = gd

        # length form ..........................

        # course grid contribution
        # <i|r|j> is the negative of the dipole moment (because of negative
        # e- charge)
        me = - gd.calculate_dipole_moment(self.get())

        # augmentation contributions
        ma = np.zeros(me.shape)
        pos_av = paw.atoms.get_positions() / Bohr
        for a, P_ni in kpt.P_ani.items():
            Ra = pos_av[a]
            Pi_i = P_ni[self.i]
            Pj_i = P_ni[self.j]
            Delta_pL = wfs.setups[a].Delta_pL
            ni=len(Pi_i)
            ma0 = 0
            ma1 = np.zeros(me.shape)
            for i in range(ni):
                for j in range(ni):
                    pij = Pi_i[i]*Pj_i[j]
                    ij = packed_index(i, j, ni)
                    # L=0 term
                    ma0 += Delta_pL[ij,0]*pij
                    # L=1 terms
                    if wfs.setups[a].lmax >= 1:
                        # see spherical_harmonics.py for
                        # L=1:y L=2:z; L=3:x
                        ma1 += np.array([Delta_pL[ij,3], Delta_pL[ij,1],
                                         Delta_pL[ij,2]]) * pij
            ma += sqrt(4 * pi / 3) * ma1 + Ra * sqrt(4 * pi) * ma0
        gd.comm.sum(ma)

        self.me = sqrt(self.energy * self.fij) * ( me + ma )

        self.mur = - ( me + ma )

        # velocity form .............................

        me = np.zeros(self.mur.shape)

        # get derivatives
        dtype = self.wfj.dtype
        dwfj_cg = gd.empty((3), dtype=dtype)
        if not hasattr(gd, 'ddr'):
            gd.ddr = [Gradient(gd, c, dtype=dtype).apply for c in range(3)]
        for c in range(3):
            gd.ddr[c](self.wfj, dwfj_cg[c], kpt.phase_cd)
            me[c] = gd.integrate(self.wfi * dwfj_cg[c])

        if 0:
            me2 = np.zeros(self.mur.shape)
            for c in range(3):
                gd.ddr[c](self.wfi, dwfj_cg[c], kpt.phase_cd)
                me2[c] = gd.integrate(self.wfj * dwfj_cg[c])
            print me, -me2, me2+me

        # augmentation contributions
        ma = np.zeros(me.shape)
        for a, P_ni in kpt.P_ani.items():
            Pi_i = P_ni[self.i]
            Pj_i = P_ni[self.j]
            nabla_iiv = paw.wfs.setups[a].nabla_iiv
            for c in range(3):
                for i1, Pi in enumerate(Pi_i):
                    for i2, Pj in enumerate(Pj_i):
                        ma[c] += Pi * Pj * nabla_iiv[i1, i2, c]
        gd.comm.sum(ma)
        
        self.muv = - (me + ma) / self.energy
##        print self.mur, self.muv, self.mur - self.muv

        # magnetic transition dipole ................

        magn = np.zeros(me.shape)
        r_cg, r2_g = coordinates(gd)

        wfi_g = self.wfi
        for ci in range(3):
            cj = (ci + 1) % 3
            ck = (ci + 2) % 3
            magn[ci] = gd.integrate(wfi_g * r_cg[cj] * dwfj_cg[ck] -
                                    wfi_g * r_cg[ck] * dwfj_cg[cj]  )
        # augmentation contributions
        ma = np.zeros(magn.shape)
        for a, P_ni in kpt.P_ani.items():
            Pi_i = P_ni[self.i]
            Pj_i = P_ni[self.j]
            rnabla_iiv = paw.wfs.setups[a].rnabla_iiv
            for c in range(3):
                for i1, Pi in enumerate(Pi_i):
                    for i2, Pj in enumerate(Pj_i):
                        ma[c] += Pi * Pj * rnabla_iiv[i1, i2, c]
        gd.comm.sum(ma)
        
        self.magn = -alpha / 2. * (magn + ma)
Esempio n. 19
0
 def __init__(self, gd, a=19., center=None):
     self.gd = gd
     self.xyz, self.r2 = coordinates(gd, center)
     self.set_width(a)
Esempio n. 20
0
 def __init__(self, gd, a=19., center=None):
     self.gd = gd
     self.xyz, self.r2 = coordinates(gd, center)
     self.set_width(a)