class CoulombNEW: def __init__(self, gd, setups, spos_ac, fft=False): assert gd.comm.size == 1 self.rhot1_G = gd.empty() self.rhot2_G = gd.empty() self.pot_G = gd.empty() self.dv = gd.dv if fft: self.poisson = FFTPoissonSolver() else: self.poisson = PoissonSolver(name='fd', nn=3) self.poisson.set_grid_descriptor(gd) self.setups = setups # Set coarse ghat self.Ghat = LFC(gd, [setup.ghat_l for setup in setups], integral=sqrt(4 * pi)) self.Ghat.set_positions(spos_ac) def calculate(self, nt1_G, nt2_G, P1_ap, P2_ap): I = 0.0 self.rhot1_G[:] = nt1_G self.rhot2_G[:] = nt2_G Q1_aL = {} Q2_aL = {} for a, P1_p in P1_ap.items(): P2_p = P2_ap[a] setup = self.setups[a] # Add atomic corrections to integral I += 2 * np.dot(P1_p, np.dot(setup.M_pp, P2_p)) # Add compensation charges to pseudo densities Q1_aL[a] = np.dot(P1_p, setup.Delta_pL) Q2_aL[a] = np.dot(P2_p, setup.Delta_pL) self.Ghat.add(self.rhot1_G, Q1_aL) self.Ghat.add(self.rhot2_G, Q2_aL) # Add coulomb energy of compensated pseudo densities to integral self.poisson.solve(self.pot_G, self.rhot2_G, charge=None, eps=1e-12, zero_initial_phi=True) I += np.vdot(self.rhot1_G, self.pot_G) * self.dv return I * Hartree
class CoulombNEW: def __init__(self, gd, setups, spos_ac, fft=False): assert gd.comm.size == 1 self.rhot1_G = gd.empty() self.rhot2_G = gd.empty() self.pot_G = gd.empty() self.dv = gd.dv if fft: self.poisson = FFTPoissonSolver() else: self.poisson = PoissonSolver(nn=3) self.poisson.set_grid_descriptor(gd) self.poisson.initialize() self.setups = setups # Set coarse ghat self.Ghat = LFC(gd, [setup.ghat_l for setup in setups], integral=sqrt(4 * pi)) self.Ghat.set_positions(spos_ac) def calculate(self, nt1_G, nt2_G, P1_ap, P2_ap): I = 0.0 self.rhot1_G[:] = nt1_G self.rhot2_G[:] = nt2_G Q1_aL = {} Q2_aL = {} for a, P1_p in P1_ap.items(): P2_p = P2_ap[a] setup = self.setups[a] # Add atomic corrections to integral I += 2 * np.dot(P1_p, np.dot(setup.M_pp, P2_p)) # Add compensation charges to pseudo densities Q1_aL[a] = np.dot(P1_p, setup.Delta_pL) Q2_aL[a] = np.dot(P2_p, setup.Delta_pL) self.Ghat.add(self.rhot1_G, Q1_aL) self.Ghat.add(self.rhot2_G, Q2_aL) # Add coulomb energy of compensated pseudo densities to integral self.poisson.solve(self.pot_G, self.rhot2_G, charge=None, eps=1e-12, zero_initial_phi=True) I += np.vdot(self.rhot1_G, self.pot_G) * self.dv return I * Hartree
def f(n, p): N = 2 * n gd = GridDescriptor((N, N, N), (L, L, L)) a = gd.zeros() print(a.shape) #p = PoissonSolver(nn=1, relax=relax) p.set_grid_descriptor(gd) cut = N / 2.0 * 0.9 s = Spline(l=0, rmax=cut, f_g=np.array([1, 0.5, 0.0])) c = LFC(gd, [[s], [s]]) c.set_positions([(0, 0, 0), (0.5, 0.5, 0.5)]) c.add(a) I0 = gd.integrate(a) a -= I0 / L**3 b = gd.zeros() p.solve(b, a, charge=0, eps=1e-20) return gd.collect(b, broadcast=1)
def f(n, p): N = 2 * n gd = GridDescriptor((N, N, N), (L, L, L)) a = gd.zeros() print(a.shape) #p = PoissonSolver(nn=1, relax=relax) p.set_grid_descriptor(gd) p.initialize() cut = N / 2.0 * 0.9 s = Spline(l=0, rmax=cut, f_g=np.array([1, 0.5, 0.0])) c = LFC(gd, [[s], [s]]) c.set_positions([(0, 0, 0), (0.5, 0.5, 0.5)]) c.add(a) I0 = gd.integrate(a) a -= gd.integrate(a) / L**3 I = gd.integrate(a) b = gd.zeros() p.solve(b, a, charge=0)#, eps=1e-20) return gd.collect(b, broadcast=1)
from gpaw.test import equal from gpaw.grid_descriptor import GridDescriptor from gpaw.spline import Spline import gpaw.mpi as mpi from gpaw.lfc import LocalizedFunctionsCollection as LFC s = Spline(0, 1.0, [1.0, 0.5, 0.0]) n = 40 a = 8.0 gd = GridDescriptor((n, n, n), (a, a, a), comm=mpi.serial_comm) c = LFC(gd, [[s], [s], [s]]) c.set_positions([(0.5, 0.5, 0.25 + 0.25 * i) for i in [0, 1, 2]]) b = gd.zeros() c.add(b) x = gd.integrate(b) gd = GridDescriptor((n, n, n), (a, a, a), comm=mpi.serial_comm) c = LFC(gd, [[s], [s], [s]]) c.set_positions([(0.5, 0.5, 0.25 + 0.25 * i) for i in [0, 1, 2]]) b = gd.zeros() c.add(b) y = gd.integrate(b) equal(x, y, 1e-13)
from gpaw.spline import Spline a = 4.0 gd = GridDescriptor(N_c=[16, 20, 20], cell_cv=[a, a + 1, a + 2], pbc_c=(0, 1, 1)) spos_ac = np.array([[0.25, 0.15, 0.35], [0.5, 0.5, 0.5]]) kpts_kc = None s = Spline(l=0, rmax=2.0, f_g=np.array([1, 0.9, 0.1, 0.0])) p = Spline(l=1, rmax=2.0, f_g=np.array([1, 0.9, 0.1, 0.0])) spline_aj = [[s], [s, p]] c = LFC(gd, spline_aj, cut=True, forces=True) c.set_positions(spos_ac) C_ani = c.dict(3, zero=True) if 1 in C_ani: C_ani[1][:, 1:] = np.eye(3) psi = gd.zeros(3) c.add(psi, C_ani) c.integrate(psi, C_ani) if 1 in C_ani: d = C_ani[1][:, 1:].diagonal() assert d.ptp() < 4e-6 C_ani[1][:, 1:] -= np.diag(d) assert abs(C_ani[1]).max() < 5e-17 d_aniv = c.dict(3, derivative=True) c.derivative(psi, d_aniv) if 1 in d_aniv: for v in range(3): assert abs(d_aniv[1][v - 1, 0, v] + 0.2144) < 5e-5 d_aniv[1][v - 1, 0, v] = 0 assert abs(d_aniv[1]).max() < 3e-16 eps = 0.0001 pos_av = np.dot(spos_ac, gd.cell_cv)
class ELF: """ELF object for calculating the electronic localization function. Arguments: =============== ===================================================== ``paw`` Instance of ``GPAW`` class. ``ncut`` Density cutoff below which the ELF is zero. =============== ===================================================== """ def __init__(self, paw=None, ncut=1e-6): """Create the ELF object.""" self.gd = paw.wfs.gd self.paw = paw self.finegd = paw.density.finegd self.nspins = paw.density.nspins self.density = paw.density self.ncut = ncut self.spinpol = (self.nspins == 2) self.initialize(paw) def initialize(self, paw): if not paw.initialized: raise RuntimeError('PAW instance is not initialized') paw.converge_wave_functions() self.tauct = LFC(self.gd, [[setup.tauct] for setup in self.density.setups], forces=True, cut=True) self.tauct.set_positions(paw.spos_ac) self.taut_sg = None self.nt_grad2_sG = self.gd.empty(self.nspins) self.nt_grad2_sg = None def interpolate(self): self.density.interpolate_pseudo_density() if self.taut_sg is None: self.taut_sg = self.finegd.empty(self.nspins) self.nt_grad2_sg = self.finegd.empty(self.nspins) ddr_v = [Gradient(self.finegd, v, n=3).apply for v in range(3)] self.nt_grad2_sg[:] = 0.0 d_g = self.finegd.empty() # Transfer the densities from the coarse to the fine grid for s in range(self.nspins): self.density.interpolator.apply(self.taut_sG[s], self.taut_sg[s]) #self.density.interpolator.apply(self.nt_grad2_sG[s], # self.nt_grad2_sg[s]) for v in range(3): ddr_v[v](self.density.nt_sg[s], d_g) self.nt_grad2_sg[s] += d_g**2.0 def update(self): self.taut_sG = self.paw.wfs.calculate_kinetic_energy_density() # Add the pseudo core kinetic array for taut_G in self.taut_sG: self.tauct.add(taut_G, 1.0 / self.paw.wfs.nspins) # For periodic boundary conditions if self.paw.wfs.kd.symmetry is not None: self.paw.wfs.kd.symmetry.symmetrize(self.taut_sG[0], self.paw.wfs.gd) self.nt_grad2_sG[:] = 0.0 d_G = self.gd.empty() for s in range(self.nspins): for v in range(3): self.paw.wfs.taugrad_v[v](self.density.nt_sG[s], d_G) self.nt_grad2_sG[s] += d_G**2.0 # TODO are nct from setups usable for nt_grad2_sG ? def get_electronic_localization_function(self, gridrefinement=1, pad=True, broadcast=True): # Returns dimensionless electronic localization function if gridrefinement == 1: elf_G = _elf(self.density.nt_sG, self.nt_grad2_sG, self.taut_sG, self.ncut, self.spinpol) elf_G = self.gd.collect(elf_G, broadcast=broadcast) if pad: elf_G = self.gd.zero_pad(elf_G) return elf_G elif gridrefinement == 2: if self.nt_grad2_sg is None: self.interpolate() elf_g = _elf(self.density.nt_sg, self.nt_grad2_sg, self.taut_sg, self.ncut, self.spinpol) elf_g = self.finegd.collect(elf_g, broadcast=broadcast) if pad: elf_g = self.finegd.zero_pad(elf_g) return elf_g else: raise NotImplementedError('Arbitrary refinement not implemented')
a = 2.5 * rc n = 64 lmax = 2 b = 8.0 m = (lmax + 1)**2 gd = GridDescriptor([n, n, n], [a, a, a]) r = np.linspace(0, rc, 200) g = np.exp(-(r / rc * b)**2) splines = [Spline(l=l, rmax=rc, f_g=g) for l in range(lmax + 1)] c = LFC(gd, [splines]) c.set_positions([(0.5, 0.5, 0.5)]) psi = gd.zeros(m) d0 = c.dict(m) if 0 in d0: d0[0] = np.identity(m) c.add(psi, d0) # Calculate on 3d-grid < phi_i | e**(-ik.r) | phi_j > R_a = np.array([a / 2, a / 2, a / 2]) rr = gd.get_grid_point_coordinates() for dim in range(3): rr[dim] -= R_a[dim] k_G = np.array([[11., 0.2, 0.1], [10., 0., 10.]]) nkpt = k_G.shape[0] d0 = np.zeros((nkpt, m, m), dtype=complex) for i in range(m): for j in range(m): for ik in range(nkpt): k = k_G[ik]
from __future__ import print_function import numpy as np from gpaw.lfc import LocalizedFunctionsCollection as LFC from gpaw.grid_descriptor import GridDescriptor from gpaw.spline import Spline gd = GridDescriptor([20, 16, 16], [(4, 2, 0), (0, 4, 0), (0, 0, 4)]) spos_ac = np.array([[0.252, 0.15, 0.35], [0.503, 0.5, 0.5]]) s = Spline(l=0, rmax=2.0, f_g=np.array([1, 0.9, 0.1, 0.0])) spline_aj = [[s], [s]] c = LFC(gd, spline_aj) c.set_positions(spos_ac) c_ai = c.dict(zero=True) if 1 in c_ai: c_ai[1][0] = 2.0 psi = gd.zeros() c.add(psi, c_ai) d_avv = dict([(a, np.zeros((3, 3))) for a in c.my_atom_indices]) c.second_derivative(psi, d_avv) if 0 in d_avv: print(d_avv[0]) eps = 0.000001 d_aiv = c.dict(derivative=True) pos_av = np.dot(spos_ac, gd.cell_cv) for v in range(3): pos_av[0, v] += eps c.set_positions(np.dot(pos_av, gd.icell_cv.T)) c.derivative(psi, d_aiv) if 0 in d_aiv:
a = 4.0 gd = GridDescriptor(N_c=[16, 20, 20], cell_cv=[a, a + 1, a + 2], pbc_c=(0, 1, 1)) spos_ac = np.array([[0.25, 0.15, 0.35], [0.5, 0.5, 0.5]]) kpts_kc = None s = Spline(l=0, rmax=2.0, f_g=np.array([1, 0.9, 0.1, 0.0])) p = Spline(l=1, rmax=2.0, f_g=np.array([1, 0.9, 0.1, 0.0])) spline_aj = [[s], [s, p]] c = LFC(gd, spline_aj, cut=True, forces=True) c.set_positions(spos_ac) C_ani = c.dict(3, zero=True) if 1 in C_ani: C_ani[1][:, 1:] = np.eye(3) psi = gd.zeros(3) c.add(psi, C_ani) c.integrate(psi, C_ani) if 1 in C_ani: d = C_ani[1][:, 1:].diagonal() assert d.ptp() < 4e-6 C_ani[1][:, 1:] -= np.diag(d) assert abs(C_ani[1]).max() < 5e-17 d_aniv = c.dict(3, derivative=True) c.derivative(psi, d_aniv) if 1 in d_aniv: for v in range(3): assert abs(d_aniv[1][v - 1, 0, v] + 0.2144) < 5e-5 d_aniv[1][v - 1, 0, v] = 0 assert abs(d_aniv[1]).max() < 3e-16 eps = 0.0001 pos_av = np.dot(spos_ac, gd.cell_cv)
a = 2.5 * rc n = 64 lmax = 2 b = 8.0 m = (lmax + 1)**2 gd = GridDescriptor([n, n, n], [a, a, a]) r = np.linspace(0, rc, 200) g = np.exp(-(r / rc * b)**2) splines = [Spline(l=l, rmax=rc, f_g=g) for l in range(lmax + 1)] c = LFC(gd, [splines]) c.set_positions([(0.5, 0.5, 0.5)]) psi = gd.zeros(m) d0 = c.dict(m) if 0 in d0: d0[0] = np.identity(m) c.add(psi, d0) # Calculate on 3d-grid < phi_i | e**(-ik.r) | phi_j > R_a = np.array([a/2,a/2,a/2]) rr = gd.get_grid_point_coordinates() for dim in range(3): rr[dim] -= R_a[dim] k_G = np.array([[11.,0.2,0.1],[10., 0., 10.]]) nkpt = k_G.shape[0] d0 = np.zeros((nkpt,m,m), dtype=complex) for i in range(m): for j in range(m): for ik in range(nkpt): k = k_G[ik]
class ELF: """ELF object for calculating the electronic localization function. Arguments: =============== ===================================================== ``paw`` Instance of ``GPAW`` class. ``ncut`` Density cutoff below which the ELF is zero. =============== ===================================================== """ def __init__(self, paw=None, ncut=1e-6): """Create the ELF object.""" self.gd = paw.wfs.gd self.paw = paw self.finegd = paw.density.finegd self.nspins = paw.density.nspins self.density = paw.density self.ncut = ncut self.spinpol = (self.nspins == 2) self.initialize(paw) def initialize(self, paw): if not paw.initialized: raise RuntimeError('PAW instance is not initialized') paw.converge_wave_functions() self.tauct = LFC(self.gd, [[setup.tauct] for setup in self.density.setups], forces=True, cut=True) spos_ac = paw.atoms.get_scaled_positions() % 1.0 self.tauct.set_positions(spos_ac) self.taut_sg = None self.nt_grad2_sG = self.gd.empty(self.nspins) self.nt_grad2_sg = None def interpolate(self): self.density.interpolate_pseudo_density() if self.taut_sg is None: self.taut_sg = self.finegd.empty(self.nspins) self.nt_grad2_sg = self.finegd.empty(self.nspins) ddr_v = [Gradient(self.finegd, v, n=3).apply for v in range(3)] self.nt_grad2_sg[:] = 0.0 d_g = self.finegd.empty() # Transfer the densities from the coarse to the fine grid for s in range(self.nspins): self.density.interpolator.apply(self.taut_sG[s], self.taut_sg[s]) #self.density.interpolator.apply(self.nt_grad2_sG[s], # self.nt_grad2_sg[s]) for v in range(3): ddr_v[v](self.density.nt_sg[s], d_g) self.nt_grad2_sg[s] += d_g**2.0 def update(self): self.taut_sG = self.paw.wfs.calculate_kinetic_energy_density() # Add the pseudo core kinetic array for taut_G in self.taut_sG: self.tauct.add(taut_G, 1.0 / self.paw.wfs.nspins) # For periodic boundary conditions if self.paw.wfs.symmetry is not None: self.paw.wfs.symmetry.symmetrize(self.taut_sG[0], self.paw.wfs.gd) self.nt_grad2_sG[:] = 0.0 d_G = self.gd.empty() for s in range(self.nspins): for v in range(3): self.paw.wfs.taugrad_v[v](self.density.nt_sG[s], d_G) self.nt_grad2_sG[s] += d_G**2.0 #TODO are nct from setups usable for nt_grad2_sG ? def get_electronic_localization_function(self, gridrefinement=1, pad=True, broadcast=True): # Returns dimensionless electronic localization function if gridrefinement == 1: elf_G = _elf(self.density.nt_sG, self.nt_grad2_sG, self.taut_sG, self.ncut, self.spinpol) elf_G = self.gd.collect(elf_G, broadcast) if pad: elf_G = self.gd.zero_pad(elf_G) return elf_G elif gridrefinement == 2: if self.nt_grad2_sg is None: self.interpolate() elf_g = _elf(self.density.nt_sg, self.nt_grad2_sg, self.taut_sg, self.ncut, self.spinpol) elf_g = self.finegd.collect(elf_g, broadcast) if pad: elf_g = self.finegd.zero_pad(elf_g) return elf_g else: raise NotImplementedError('Arbitrary refinement not implemented')
import numpy as np from gpaw.lfc import LocalizedFunctionsCollection as LFC from gpaw.grid_descriptor import GridDescriptor from gpaw.spline import Spline gd = GridDescriptor([20, 16, 16], [(4, 2, 0), (0, 4, 0), (0, 0, 4)]) spos_ac = np.array([[0.252, 0.15, 0.35], [0.503, 0.5, 0.5]]) s = Spline(l=0, rmax=2.0, f_g=np.array([1, 0.9, 0.1, 0.0])) spline_aj = [[s], [s]] c = LFC(gd, spline_aj) c.set_positions(spos_ac) c_ai = c.dict(zero=True) if 1 in c_ai: c_ai[1][0] = 2.0 psi = gd.zeros() c.add(psi, c_ai) d_avv = dict([(a, np.zeros((3, 3))) for a in c.my_atom_indices]) c.second_derivative(psi, d_avv) if 0 in d_avv: print d_avv[0] eps = 0.000001 d_aiv = c.dict(derivative=True) pos_av = np.dot(spos_ac, gd.cell_cv) for v in range(3): pos_av[0, v] += eps c.set_positions(np.dot(pos_av, gd.icell_cv.T)) c.derivative(psi, d_aiv) if 0 in d_aiv: d0_v = d_aiv[0][0].copy()