def initialize(self, density, hamiltonian, wfs, occupations): assert wfs.kd.gamma self.xc.initialize(density, hamiltonian, wfs, occupations) self.kpt_comm = wfs.kd.comm self.nspins = wfs.nspins self.setups = wfs.setups self.density = density self.kpt_u = wfs.kpt_u self.exx_s = np.zeros(self.nspins) self.ekin_s = np.zeros(self.nspins) self.nocc_s = np.empty(self.nspins, int) if self.finegrid: self.poissonsolver = hamiltonian.poisson self.ghat = density.ghat self.interpolator = density.interpolator self.restrictor = hamiltonian.restrictor else: self.poissonsolver = PoissonSolver(eps=1e-11) self.poissonsolver.set_grid_descriptor(density.gd) self.poissonsolver.initialize() self.ghat = LFC(density.gd, [setup.ghat_l for setup in density.setups], integral=np.sqrt(4 * np.pi), forces=True) self.gd = density.gd self.finegd = self.ghat.gd
def __init__(self, gd, finegd, nspins, setups, timer, xc, world, kptband_comm, vext=None, collinear=True, psolver=None, stencil=3): Hamiltonian.__init__(self, gd, finegd, nspins, setups, timer, xc, world, kptband_comm, vext, collinear) # Solver for the Poisson equation: if psolver is None: psolver = PoissonSolver(nn=3, relax='J') self.poisson = psolver self.poisson.set_grid_descriptor(finegd) # Restrictor function for the potential: self.restrictor = Transformer(self.finegd, self.gd, stencil) self.restrict = self.restrictor.apply self.vbar = LFC(self.finegd, [[setup.vbar] for setup in setups], forces=True) self.vbar_g = None
def load(self, method): """Make sure all necessary attributes have been initialized""" assert method in ('real', 'recip_gauss', 'recip_ewald'),\ str(method) + ' is an invalid method name,\n' +\ 'use either real, recip_gauss, or recip_ewald' if method.startswith('recip'): if self.gd.comm.size > 1: raise RuntimeError("Cannot do parallel FFT, use method='real'") if not hasattr(self, 'k2'): self.k2, self.N3 = construct_reciprocal(self.gd) if method.endswith('ewald') and not hasattr(self, 'ewald'): # cutoff radius assert self.gd.orthogonal rc = 0.5 * np.average(self.gd.cell_cv.diagonal()) # ewald potential: 1 - cos(k rc) self.ewald = (np.ones(self.gd.n_c) - np.cos(np.sqrt(self.k2) * rc)) # lim k -> 0 ewald / k2 self.ewald[0, 0, 0] = 0.5 * rc**2 elif method.endswith('gauss') and not hasattr(self, 'ng'): gauss = Gaussian(self.gd) self.ng = gauss.get_gauss(0) / sqrt(4 * pi) self.vg = gauss.get_gauss_pot(0) / sqrt(4 * pi) else: # method == 'real' if not hasattr(self, 'solve'): if self.poisson is not None: self.solve = self.poisson.solve else: solver = PoissonSolver(nn=2) solver.set_grid_descriptor(self.gd) solver.initialize(load_gauss=True) self.solve = solver.solve
def initialize(self, density, hamiltonian, wfs, occ=None): assert wfs.kd.gamma assert not wfs.gd.pbc_c.any() self.wfs = wfs self.dtype = float self.xc.initialize(density, hamiltonian, wfs, occ) self.kpt_comm = wfs.kd.comm self.nspins = wfs.nspins self.nbands = wfs.bd.nbands if self.finegrid: self.finegd = density.finegd self.ghat = density.ghat else: self.finegd = density.gd self.ghat = LFC(self.finegd, [setup.ghat_l for setup in density.setups], integral=sqrt(4 * pi), forces=True) poissonsolver = PoissonSolver(eps=1e-14) poissonsolver.set_grid_descriptor(self.finegd) poissonsolver.initialize() self.spin_s = {} for kpt in wfs.kpt_u: self.spin_s[kpt.s] = SICSpin(kpt, self.xc, density, hamiltonian, wfs, poissonsolver, self.ghat, self.finegd, **self.parameters)
def calculate_field( gd, rho_g, bgef_v, phi_g, ef_vg, fe_g, # preallocated numpy arrays nv=3, poisson_nn=3, poisson_relax='J', gradient_n=3, poisson_eps=1e-20): dtype = rho_g.dtype yes_complex = dtype == complex phi_g[:] = 0.0 ef_vg[:] = 0.0 fe_g[:] = 0.0 tmp_g = gd.zeros(dtype=float) # Poissonsolver poissonsolver = PoissonSolver(nn=poisson_nn, relax=poisson_relax, eps=poisson_eps) poissonsolver.set_grid_descriptor(gd) poissonsolver.initialize() # Potential, real part poissonsolver.solve(tmp_g, rho_g.real.copy()) phi_g += tmp_g # Potential, imag part if yes_complex: tmp_g[:] = 0.0 poissonsolver.solve(tmp_g, rho_g.imag.copy()) phi_g += 1.0j * tmp_g # Gradient gradient = [Gradient(gd, v, scale=1.0, n=gradient_n) for v in range(nv)] for v in range(nv): # Electric field, real part gradient[v].apply(-phi_g.real, tmp_g) ef_vg[v] += tmp_g # Electric field, imag part if yes_complex: gradient[v].apply(-phi_g.imag, tmp_g) ef_vg[v] += 1.0j * tmp_g # Electric field enhancement tmp_g[:] = 0.0 # total electric field norm bgefnorm = 0.0 # background electric field norm for v in range(nv): tmp_g += np.absolute(bgef_v[v] + ef_vg[v])**2 bgefnorm += np.absolute(bgef_v[v])**2 tmp_g = np.sqrt(tmp_g) bgefnorm = np.sqrt(bgefnorm) fe_g[:] = tmp_g / bgefnorm
def prepare(setups): calc = GPAW(basis={'H' : b}, mode='lcao', setups=setups, h=0.2, poissonsolver=PoissonSolver('M', relax='GS', eps=1e-5), spinpol=False, nbands=1) system.set_calculator(calc) return calc
def get_calculator(): calc = GPAW(h=0.2, mode = 'lcao', basis = 'szp(dzp)', mixer=Mixer(beta=0.1, nmaxold=5, weight=50.0), poissonsolver=PoissonSolver(nn='M', relax='GS'), txt='C5H12.txt') return calc
def solve(self): hamiltonian = self.calculator.hamiltonian self.poisson = PoissonSolver('fd', nn=hamiltonian.poisson.nn) self.poisson.set_grid_descriptor(self.gd) self.poisson.initialize() corrt_G = self.gd.empty() self.poisson.solve(corrt_G, self.vt_G, charge=None) corrt_G /= (2 * pi)**(5. / 2) self.corrt_G = corrt_G
def get_calculator(): calc = GPAW(gpts=(64, 64, 64), #h=0.18, gives 64x60x60 mode='lcao', basis='szp(dzp)', nbands=-5, xc='LDA', width=0.1, mixer=Mixer(beta=0.1, nmaxold=5, weight=50.0), poissonsolver=PoissonSolver(nn='M', relax='GS'), convergence={'energy': 1e-4, 'bands': -3}, stencils=(3, 3), txt='nanoparticle.txt') return calc
def initialize(self, density, hamiltonian, wfs, occupations): assert wfs.kd.gamma self.xc.initialize(density, hamiltonian, wfs, occupations) self.kpt_comm = wfs.kd.comm self.nspins = wfs.nspins self.setups = wfs.setups self.density = density self.kpt_u = wfs.kpt_u self.exx_s = np.zeros(self.nspins) self.ekin_s = np.zeros(self.nspins) self.nocc_s = np.empty(self.nspins, int) self.gd = density.gd self.redistributor = density.redistributor use_charge_center = hamiltonian.poisson.use_charge_center # XXX How do we construct a copy of the Poisson solver of the # Hamiltonian? We don't know what class it is, etc., but gd # may differ. # XXX One might consider using a charged centered compensation # charge for the PoissonSolver in the case of EXX as standard self.poissonsolver = PoissonSolver('fd', eps=1e-11, use_charge_center=use_charge_center) # self.poissonsolver = hamiltonian.poisson if self.finegrid: self.finegd = self.gd.refine() # XXX Taking restrictor from Hamiltonian will not work in PW mode, # will it? I think this supports only real-space mode. # self.restrictor = hamiltonian.restrictor self.restrictor = Transformer(self.finegd, self.gd, 3) self.interpolator = Transformer(self.gd, self.finegd, 3) else: self.finegd = self.gd self.ghat = LFC(self.finegd, [setup.ghat_l for setup in density.setups], integral=np.sqrt(4 * np.pi), forces=True) self.poissonsolver.set_grid_descriptor(self.finegd) if self.rsf == 'Yukawa': omega2 = self.omega**2 self.screened_poissonsolver = HelmholtzSolver( k2=-omega2, eps=1e-11, nn=3, use_charge_center=use_charge_center) self.screened_poissonsolver.set_grid_descriptor(self.finegd)
def get_calculator(): basis = 'szp(dzp)' calc = GPAW( gpts=(64, 64, 128), # ca h=0.25 width=0.1, nbands=-5, xc='LDA', mode='lcao', txt='C2_Cu100.txt', mixer=Mixer(beta=0.1, nmaxold=5, weight=50.0), poissonsolver=PoissonSolver(nn='M', relax='GS'), stencils=(3, 3), maxiter=400, basis=basis) return calc
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 __init__(self, gd, finegd, nspins, setups, stencil, timer, xc, psolver, vext_g): """Create the Hamiltonian.""" self.gd = gd self.finegd = finegd self.nspins = nspins self.setups = setups self.timer = timer self.xc = xc # Solver for the Poisson equation: if psolver is None: psolver = PoissonSolver(nn=3, relax='J') self.poisson = psolver self.poisson.set_grid_descriptor(finegd) self.dH_asp = None # The external potential self.vext_g = vext_g self.vt_sG = None self.vHt_g = None self.vt_sg = None self.vbar_g = None self.rank_a = None # Restrictor function for the potential: self.restrictor = Transformer(self.finegd, self.gd, stencil, allocate=False) self.restrict = self.restrictor.apply self.vbar = LFC(self.finegd, [[setup.vbar] for setup in setups], forces=True) self.Ekin0 = None self.Ekin = None self.Epot = None self.Ebar = None self.Eext = None self.Exc = None self.Etot = None self.S = None self.allocated = False
def calc_eng_homo_lumo(atoms): # set gpaw calculator calc = GPAW( h=0.16, kpts=(1, 1, 1), xc='B3LYP', occupations=FermiDirac(width=0.1), # eigensolver=Davidson(3), eigensolver=RMMDIIS(), poissonsolver=PoissonSolver(eps=1e-12), maxiter=2000) atoms.calc = calc energy = atoms.get_potential_energy() print(energy) (h**o, lumo) = calc.get_homo_lumo() print("h**o: {} and LUMO: {}".format(h**o, lumo)) return h**o, lumo
def initialize(self, density, hamiltonian, wfs, occupations): assert wfs.kd.gamma self.xc.initialize(density, hamiltonian, wfs, occupations) self.kpt_comm = wfs.kd.comm self.nspins = wfs.nspins self.setups = wfs.setups self.density = density self.kpt_u = wfs.kpt_u self.exx_s = np.zeros(self.nspins) self.ekin_s = np.zeros(self.nspins) self.nocc_s = np.empty(self.nspins, int) self.gd = density.gd self.redistributor = density.redistributor # XXX How do we construct a copy of the Poisson solver of the # Hamiltonian? We don't know what class it is, etc., but gd # may differ. self.poissonsolver = PoissonSolver(eps=1e-11) #self.poissonsolver = hamiltonian.poisson if self.finegrid: self.finegd = self.gd.refine() # XXX Taking restrictor from Hamiltonian will not work in PW mode, # will it? I think this supports only real-space mode. #self.restrictor = hamiltonian.restrictor self.restrictor = Transformer(self.finegd, self.gd, 3) self.interpolator = Transformer(self.gd, self.finegd, 3) else: self.finegd = self.gd self.ghat = LFC(self.finegd, [setup.ghat_l for setup in density.setups], integral=np.sqrt(4 * np.pi), forces=True) self.poissonsolver.set_grid_descriptor(self.finegd) self.poissonsolver.initialize()
from gpaw.mpi import world from gpaw.test import equal # Atoms atoms = molecule('Na2') atoms.center(vacuum=4.0) # Ground-state calculation calc = GPAW(nbands=2, h=0.4, setups=dict(Na='1'), basis='sz(dzp)', mode='lcao', xc='oldLDA', poissonsolver=PoissonSolver(eps=1e-16), convergence={'density': 1e-8}, txt='gs.out') atoms.set_calculator(calc) energy = atoms.get_potential_energy() calc.write('gs.gpw', mode='all') # Time-propagation calculation td_calc = LCAOTDDFT('gs.gpw', txt='td.out') DipoleMomentWriter(td_calc, 'dm.dat') td_calc.absorption_kick([0, 0, 1e-5]) td_calc.propagate(30, 150) photoabsorption_spectrum('dm.dat', 'spec.dat', e_max=10, width=0.5,
basis = BasisMaker('Na').generate(1, 1, energysplit=0.3) atoms = Atoms('Na12', pbc=(1, 1, 1), cell=[L, L, 12 * a]) atoms.positions[:12, 2] = [i * a for i in range(12)] atoms.positions[:, :2] = L / 2. atoms.center() pl_atoms1 = range(4) pl_atoms2 = range(8, 12) pl_cell1 = (L, L, 4 * a) pl_cell2 = pl_cell1 t = Transport(h=0.3, xc='LDA', basis={'Na': basis}, kpts=(2, 2, 1), occupations=FermiDirac(0.1), mode='lcao', poissonsolver=PoissonSolver(nn=2, relax='GS'), txt='Na_lcao.txt', mixer=Mixer(0.1, 5, weight=100.0), guess_steps=10, pl_atoms=[pl_atoms1, pl_atoms2], pl_cells=[pl_cell1, pl_cell2], pl_kpts=(2, 2, 15), analysis_data_list=['tc'], edge_atoms=[[0, 3], [0, 11]], mol_atoms=range(4, 8)) atoms.set_calculator(t) t.calculate_iv(0.5, 2)
"""Test poisson solver for asymmetric charges.""" from __future__ import print_function from gpaw.utilities.gauss import Gaussian from gpaw.grid_descriptor import GridDescriptor from gpaw.poisson import PoissonSolver # Initialize classes a = 20.0 # Size of cell inv_width = 19 # inverse width of the gaussian N = 48 # Number of grid points center_of_charge = (a / 2, a / 2, 3 * a / 4) # off center charge 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, use_charge_center=True) solver.set_grid_descriptor(gd) solver.initialize() gauss = Gaussian(gd, a=inv_width, center=center_of_charge) test_poisson = Gaussian(gd, a=inv_width, center=center_of_charge) # /-------------------------------------------------\ # | Check if Gaussian potentials are made correctly | # \-------------------------------------------------/ # Array for storing the potential pot = gd.zeros(dtype=float, global_array=False) solver.load_gauss() vg = test_poisson.get_gauss_pot(0) # Get analytic functions ng = gauss.get_gauss(0) # vg = solver.phi_gauss
from gpaw.utilities.gauss import Gaussian from gpaw.grid_descriptor import GridDescriptor from gpaw.test import equal 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):
def calculate_induced_field(self, from_density='comp', gridrefinement=2, extend_N_cd=None, deextend=False, poissonsolver=None, gradient_n=3): if self.has_field and \ from_density == self.field_from_density and \ self.Frho_wg is not None: Frho_wg = self.Frho_wg gd = self.fieldgd else: Frho_wg, gd = self.get_induced_density(from_density, gridrefinement) # Always extend a bit to get field without jumps if extend_N_cd is None: extend_N = max(8, 2**int(np.ceil(np.log(gradient_n) / np.log(2.)))) extend_N_cd = extend_N * np.ones(shape=(3, 2), dtype=np.int) deextend = True # Extend grid oldgd = gd egd, cell_cv, move_c = \ extended_grid_descriptor(gd, extend_N_cd=extend_N_cd) Frho_we = egd.zeros((self.nw, ), dtype=self.dtype) for w in range(self.nw): extend_array(gd, egd, Frho_wg[w], Frho_we[w]) Frho_wg = Frho_we gd = egd if not deextend: # TODO: this will make atoms unusable with original grid self.atoms.set_cell(cell_cv, scale_atoms=False) move_atoms(self.atoms, move_c) # Allocate arrays Fphi_wg = gd.zeros((self.nw, ), dtype=self.dtype) Fef_wvg = gd.zeros(( self.nw, self.nv, ), dtype=self.dtype) Ffe_wg = gd.zeros((self.nw, ), dtype=float) # Poissonsolver if poissonsolver is None: poissonsolver = PoissonSolver(name='fd', eps=1e-20) poissonsolver.set_grid_descriptor(gd) for w in range(self.nw): # TODO: better output of progress # parprint('%d' % w) calculate_field(gd, Frho_wg[w], self.Fbgef_v, Fphi_wg[w], Fef_wvg[w], Ffe_wg[w], poissonsolver=poissonsolver, nv=self.nv, gradient_n=gradient_n) # De-extend grid if deextend: Frho_wo = oldgd.zeros((self.nw, ), dtype=self.dtype) Fphi_wo = oldgd.zeros((self.nw, ), dtype=self.dtype) Fef_wvo = oldgd.zeros(( self.nw, self.nv, ), dtype=self.dtype) Ffe_wo = oldgd.zeros((self.nw, ), dtype=float) for w in range(self.nw): deextend_array(oldgd, gd, Frho_wo[w], Frho_wg[w]) deextend_array(oldgd, gd, Fphi_wo[w], Fphi_wg[w]) deextend_array(oldgd, gd, Ffe_wo[w], Ffe_wg[w]) for v in range(self.nv): deextend_array(oldgd, gd, Fef_wvo[w][v], Fef_wvg[w][v]) Frho_wg = Frho_wo Fphi_wg = Fphi_wo Fef_wvg = Fef_wvo Ffe_wg = Ffe_wo gd = oldgd # Store results self.has_field = True self.field_from_density = from_density self.fieldgd = gd self.Frho_wg = Frho_wg self.Fphi_wg = Fphi_wg self.Fef_wvg = Fef_wvg self.Ffe_wg = Ffe_wg
def set_grid_descriptor(self, qmgd): if not self.has_subsystems: return self.qm.gd = qmgd # Create quantum Poisson solver self.qm.poisson_solver = PoissonSolver( name='fd', nn=self.nn, eps=self.eps, relax=self.relax, remove_moment=self.remove_moment_qm) self.qm.poisson_solver.set_grid_descriptor(self.qm.gd) #self.qm.poisson_solver.initialize() self.qm.phi = self.qm.gd.zeros() self.qm.rho = self.qm.gd.zeros() # Set quantum grid descriptor self.qm.poisson_solver.set_grid_descriptor(qmgd) # Create classical PoissonSolver self.cl.poisson_solver = PoissonSolver( name='fd', nn=self.nn, eps=self.eps, relax=self.relax, remove_moment=self.remove_moment_cl) self.cl.poisson_solver.set_grid_descriptor(self.cl.gd) #self.cl.poisson_solver.initialize() # Initialize classical material, # its Poisson solver was generated already self.cl.poisson_solver.set_grid_descriptor(self.cl.gd) self.classical_material.initialize(self.cl.gd) self.cl.extrapolated_qm_phi = self.cl.gd.zeros() self.cl.phi = self.cl.gd.zeros() self.cl.extrapolated_qm_phi = self.cl.gd.empty() msg = self.messages.append msg('\nFDTDPoissonSolver/grid descriptors and coupler:') msg(' Domain parallelization with %i processes.' % self.cl.gd.comm.size) if self.cl.gd.comm == serial_comm: msg(' Communicator for domain parallelization: serial_comm') elif self.cl.gd.comm == world: msg(' Communicator for domain parallelization: world') elif self.cl.gd.comm == self.qm.gd.comm: msg(' Communicator for domain parallelization: dft_domain_comm') else: msg(' Communicator for domain parallelization: %s' % self.cl.gd.comm) # Initialize potential coupler if self.potential_coupling_scheme == 'Multipoles': msg('Classical-quantum coupling by multipole expansion ' + 'with maxL: %i' % (self.remove_moment_qm)) self.potential_coupler = MultipolesPotentialCoupler( qm=self.qm, cl=self.cl, index_offset_1=self.shift_indices_1, index_offset_2=self.shift_indices_2, extended_index_offset_1=self.extended_shift_indices_1, extended_index_offset_2=self.extended_shift_indices_2, extended_delta_index=self.extended_deltaIndex, num_refinements=self.num_refinements, remove_moment_qm=self.remove_moment_qm, remove_moment_cl=self.remove_moment_cl, rank=self.rank) else: msg('Classical-quantum coupling by coarsening/refining') self.potential_coupler = RefinerPotentialCoupler( qm=self.qm, cl=self.cl, index_offset_1=self.shift_indices_1, index_offset_2=self.shift_indices_2, extended_index_offset_1=self.extended_shift_indices_1, extended_index_offset_2=self.extended_shift_indices_2, extended_delta_index=self.extended_deltaIndex, num_refinements=self.num_refinements, remove_moment_qm=self.remove_moment_qm, remove_moment_cl=self.remove_moment_cl, rank=self.rank) self.phi_tot_clgd = self.cl.gd.empty() self.phi_tot_qmgd = self.qm.gd.empty()
def poisson_solve(gd, rho_g, poisson): phi_g = gd.zeros() npoisson = poisson.solve(phi_g, rho_g) return phi_g, npoisson def compare(phi1_g, phi2_g, val): big_phi1_g = gd.collect(phi1_g) big_phi2_g = gd.collect(phi2_g) if gd.comm.rank == 0: equal(np.max(np.absolute(big_phi1_g - big_phi2_g)), val, np.sqrt(poissoneps)) # Get reference from default poissonsolver poisson = PoissonSolver(eps=poissoneps) poisson.set_grid_descriptor(gd) phiref_g, npoisson = poisson_solve(gd, rho_g, poisson) # Test agreement with default poisson = ExtendedPoissonSolver(eps=poissoneps) poisson.set_grid_descriptor(gd) phi_g, npoisson = poisson_solve(gd, rho_g, poisson) plot_phi(phi_g) compare(phi_g, phiref_g, 0.0) # Test moment_corrections=int poisson = ExtendedPoissonSolver(eps=poissoneps, moment_corrections=4) poisson.set_grid_descriptor(gd) phi_g, npoisson = poisson_solve(gd, rho_g, poisson) plot_phi(phi_g)
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) b1 = f(8, PoissonSolver(nn=1, relax='J')) b2 = f(8, PoissonSolver(nn=1, relax='GS')) err1 = abs(b1[0, 0, 0] - b1[8, 8, 8]) err2 = abs(b2[0, 0, 0] - b2[8, 8, 8]) print err1 print err2 assert err1 < 6e-16 assert err2 < 3e-6 # XXX Shouldn't this be better? from gpaw.mpi import size if size == 1: b3 = f(8, FFTPoissonSolver()) err3 = abs(b3[0, 0, 0] - b3[8, 8, 8])
""" system1 = molecule('H2O') system1.set_pbc((True, True, False)) system1.center(vacuum=3.0) system1.center(vacuum=10.0, axis=2) system2 = system1.copy() system2.positions *= [1.0, 1.0, -1.0] system2 += system1 system2.center(vacuum=6.0, axis=2) calc1 = GPAW(mode='lcao', gpts=h2gpts(0.3, system1.cell, idiv=8), poissonsolver=DipoleCorrection( PoissonSolver(relax='GS', eps=1e-11), 2)) system1.set_calculator(calc1) system1.get_potential_energy() v1 = calc1.get_effective_potential(pad=False) calc2 = GPAW(mode='lcao', gpts=h2gpts(0.3, system2.cell, idiv=8), poissonsolver=PoissonSolver(relax='GS', eps=1e-11)) system2.set_calculator(calc2) system2.get_potential_energy() v2 = calc2.get_effective_potential(pad=False) def get_avg(v):
import numpy as np from ase import Atoms from gpaw import GPAW from gpaw.tddft import TDDFT from gpaw.inducedfield.inducedfield_base import BaseInducedField from gpaw.inducedfield.inducedfield_tddft import TDDFTInducedField from gpaw.poisson import PoissonSolver from gpaw.test import equal do_print_values = False # Use this for printing the reference values poisson_eps = 1e-12 density_eps = 1e-6 # PoissonSolver poissonsolver = PoissonSolver('fd', eps=poisson_eps) # Na2 cluster atoms = Atoms(symbols='Na2', positions=[(0, 0, 0), (3.0, 0, 0)], pbc=False) atoms.center(vacuum=3.0) # Standard ground state calculation calc = GPAW(nbands=2, h=0.6, setups={'Na': '1'}, poissonsolver=poissonsolver, convergence={'density': density_eps}) atoms.set_calculator(calc) energy = atoms.get_potential_energy() calc.write('na2_gs.gpw', mode='all') # Standard time-propagation initialization time_step = 10.0
from ase.io import read from gpaw import GPAW, ConvergenceError from gpaw.poisson import PoissonSolver from gpaw.dipole_correction import DipoleCorrection atoms = read('Pt_H2O.xyz') atoms.set_cell([[ 8.527708, 0., 0., ], [ 0., 4.923474, 0., ], [ 0., 0., 16., ]], scale_atoms=False) atoms.center(axis=2) atoms.pbc = (True, True, False) atoms.calc = GPAW(h=0.20, kpts=(2,4,1), xc='RPBE', poissonsolver=DipoleCorrection(PoissonSolver(),2), basis='dzp', maxiter=200, width=0.1, txt='Pt_H2O.txt', ) ncpus = 8
def read(self, reader): """Read state from file.""" if isinstance(reader, str): reader = gpaw.io.open(reader, 'r') r = reader version = r['version'] assert version >= 0.3 self.xc = r['XCFunctional'] self.nbands = r.dimension('nbands') self.spinpol = (r.dimension('nspins') == 2) if r.has_array('NBZKPoints'): self.kpts = r.get('NBZKPoints') else: self.kpts = r.get('BZKPoints') self.usesymm = r['UseSymmetry'] try: self.basis = r['BasisSet'] except KeyError: pass self.gpts = ((r.dimension('ngptsx') + 1) // 2 * 2, (r.dimension('ngptsy') + 1) // 2 * 2, (r.dimension('ngptsz') + 1) // 2 * 2) self.lmax = r['MaximumAngularMomentum'] self.setups = r['SetupTypes'] self.fixdensity = r['FixDensity'] if version <= 0.4: # Old version: XXX print('# Warning: Reading old version 0.3/0.4 restart files ' + 'will be disabled some day in the future!') self.convergence['eigenstates'] = r['Tolerance'] else: self.convergence = { 'density': r['DensityConvergenceCriterion'], 'energy': r['EnergyConvergenceCriterion'] * Hartree, 'eigenstates': r['EigenstatesConvergenceCriterion'], 'bands': r['NumberOfBandsToConverge'] } if version <= 0.6: mixer = 'Mixer' weight = r['MixMetric'] elif version <= 0.7: mixer = r['MixClass'] weight = r['MixWeight'] metric = r['MixMetric'] if metric is None: weight = 1.0 else: mixer = r['MixClass'] weight = r['MixWeight'] if mixer == 'Mixer': from gpaw.mixer import Mixer elif mixer == 'MixerSum': from gpaw.mixer import MixerSum as Mixer elif mixer == 'MixerSum2': from gpaw.mixer import MixerSum2 as Mixer elif mixer == 'MixerDif': from gpaw.mixer import MixerDif as Mixer elif mixer == 'DummyMixer': from gpaw.mixer import DummyMixer as Mixer else: Mixer = None if Mixer is None: self.mixer = None else: self.mixer = Mixer(r['MixBeta'], r['MixOld'], weight) if version == 0.3: # Old version: XXX print('# Warning: Reading old version 0.3 restart files is ' + 'dangerous and will be disabled some day in the future!') self.stencils = (2, 3) self.charge = 0.0 fixmom = False else: self.stencils = (r['KohnShamStencil'], r['InterpolationStencil']) if r['PoissonStencil'] == 999: self.poissonsolver = FFTPoissonSolver() else: self.poissonsolver = PoissonSolver(nn=r['PoissonStencil']) self.charge = r['Charge'] fixmom = r['FixMagneticMoment'] self.occupations = FermiDirac(r['FermiWidth'] * Hartree, fixmagmom=fixmom) try: self.mode = r['Mode'] except KeyError: self.mode = 'fd' try: dtype = r['DataType'] if dtype == 'Float': self.dtype = float else: self.dtype = complex except KeyError: self.dtype = float
# IP for CO using LCY-PBE with gamma=0.81 after # dx.doi.org/10.1021/acs.jctc.8b00238 IP = 14.31 if setup_paths[0] != '.': setup_paths.insert(0, '.') for atom in ['C', 'O']: gen(atom, xcname='PBE', scalarrel=True, exx=True, yukawa_gamma=0.81) h = 0.30 co = Atoms('CO', positions=[(0, 0, 0), (0, 0, 1.15)]) co.minimal_box(5) # c = {'energy': 0.005, 'eigenstates': 1e-4} # Usable values c = {'energy': 0.1, 'eigenstates': 3, 'density': 3} # Values for test calc = GPAW(txt='CO.txt', xc='LCY-PBE:omega=0.81', convergence=c, eigensolver=RMMDIIS(), h=h, poissonsolver=PoissonSolver(use_charge_center=True), occupations=FermiDirac(width=0.0), spinpol=False) co.set_calculator(calc) co.get_potential_energy() (eps_homo, eps_lumo) = calc.get_homo_lumo() equal(eps_homo, -IP, 0.15)
def compare(phi1_g, phi2_g, val, eps=np.sqrt(poissoneps)): big_phi1_g = gd.collect(phi1_g) big_phi2_g = gd.collect(phi2_g) if gd.comm.rank == 0: diff = np.max(np.absolute(big_phi1_g - big_phi2_g)) else: diff = 0.0 diff = np.array([diff]) gd.comm.broadcast(diff, 0) equal(diff[0], val, eps) # Get reference from default poissonsolver poisson = PoissonSolver('fd', eps=poissoneps) phiref_g, npoisson = poisson_init_solve(gd, rho_g, poisson) # Test agreement with default poisson = ExtraVacuumPoissonSolver(N_c, PoissonSolver('fd', eps=poissoneps)) phi_g, npoisson = poisson_init_solve(gd, rho_g, poisson) compare(phi_g, phiref_g, 0.0, 1e-24) # New reference with extra vacuum gpts = N_c * 4 poisson = ExtraVacuumPoissonSolver(gpts, PoissonSolver('fd', eps=poissoneps)) phi_g, npoisson = poisson_init_solve(gd, rho_g, poisson) # print poisson.get_description() compare(phi_g, phiref_g, 2.6485385144e-02) phiref_g = phi_g
from ase import * from gpaw.utilities import equal import numpy as np from gpaw import GPAW from gpaw.poisson import PoissonSolver a = 2.7 bulk = Atoms('Li', pbc=True, cell=(a, a, a)) k = 4 g = 8 calc = GPAW(gpts=(g, g, g), kpts=(k, k, k), nbands=2, poissonsolver=PoissonSolver(relax='GS'), txt=None) bulk.set_calculator(calc) bulk.get_potential_energy() ave_pot = np.sum(calc.hamiltonian.vHt_g.ravel()) / (2 * g)**3 equal(ave_pot, 0.0, 1e-8) calc = GPAW(gpts=(g, g, g), kpts=(k, k, k), nbands=2, poissonsolver=PoissonSolver(relax='J'), txt=None) bulk.set_calculator(calc) bulk.get_potential_energy() ave_pot = np.sum(calc.hamiltonian.vHt_g.ravel()) / (2 * g)**3 equal(ave_pot, 0.0, 1e-8)