def check_df(name, ref_energy, ref_loss, ref_energy_lfe, ref_loss_lfe, **kwargs_override): kwargs = dict(calc=calc, q=q, w=w.copy(), eta=0.5, ecut=(30, 30, 30), txt='df.%s.txt' % name) kwargs.update(kwargs_override) df = DF(**kwargs) fname = 'dfdump.%s.dat' % name df.get_EELS_spectrum(filename=fname) world.barrier() d = np.loadtxt(fname) loss = d[:, 1] loss_lfe = d[:, 2] energies = d[:, 0] #import pylab as pl #fig = pl.figure() #ax1 = fig.add_subplot(111) #ax1.plot(d[:, 0], d[:, 1]/np.max(d[:, 1])) #ax1.plot(d[:, 0], d[:, 2]/np.max(d[:, 2])) #ax1.axis(ymin=0, ymax=1) #fig.savefig('fig.%s.pdf' % name) energy, peakloss = getpeak(energies, loss) energy_lfe , peakloss_lfe = getpeak(energies, loss_lfe) check(name, energy, peakloss, ref_energy, ref_loss) check('%s-lfe' % name, energy_lfe, peakloss_lfe, ref_energy_lfe, ref_loss_lfe) line = template % (name, energy, peakloss, energy_lfe, peakloss_lfe, repr(kwargs_override)) scriptlines.append(line)
def dump_hamiltonian(filename, atoms, direction=None, Ef=None): h_skmm, s_kmm = get_hamiltonian(atoms) if direction != None: d = 'xyz'.index(direction) for s in range(atoms.calc.nspins): for k in range(atoms.calc.nkpts): if s==0: remove_pbc(atoms, h_skmm[s, k], s_kmm[k], d) else: remove_pbc(atoms, h_skmm[s, k], None, d) if atoms.calc.master: fd = file(filename,'wb') pickle.dump((h_skmm, s_kmm), fd, 2) atoms_data = {'cell':atoms.cell, 'positions':atoms.positions, 'numbers':atoms.numbers, 'pbc':atoms.pbc} pickle.dump(atoms_data, fd, 2) calc_data ={'weight_k':atoms.calc.weight_k, 'ibzk_kc':atoms.calc.ibzk_kc} pickle.dump(calc_data, fd, 2) fd.close() world.barrier()
def check_df(name, ref_energy, ref_loss, ref_energy_lfe, ref_loss_lfe, **kwargs_override): kwargs = dict(calc=calc, frequencies=w.copy(), eta=0.5, ecut=30, txt='df.%s.txt' % name) kwargs.update(kwargs_override) df = DielectricFunction(**kwargs) fname = 'dfdump.%s.dat' % name df.get_eels_spectrum('RPA',q_c=q,filename=fname) world.barrier() d = np.loadtxt(fname,delimiter=',') loss = d[:, 1] loss_lfe = d[:, 2] energies = d[:, 0] #import pylab as pl #fig = pl.figure() #ax1 = fig.add_subplot(111) #ax1.plot(d[:, 0], d[:, 1]/np.max(d[:, 1])) #ax1.plot(d[:, 0], d[:, 2]/np.max(d[:, 2])) #ax1.axis(ymin=0, ymax=1) #fig.savefig('fig.%s.pdf' % name) energy, peakloss = getpeak(energies, loss) energy_lfe , peakloss_lfe = getpeak(energies, loss_lfe) check(name, energy, peakloss, ref_energy, ref_loss) check('%s-lfe' % name, energy_lfe, peakloss_lfe, ref_energy_lfe, ref_loss_lfe) line = template % (name, energy, peakloss, energy_lfe, peakloss_lfe, repr(kwargs_override)) scriptlines.append(line)
def par_write(filename, name, comm, chi0_wGG): ## support only world communicator at the moment from gpaw.mpi import rank, size, world from gpaw.io import open assert comm.size == size assert comm.rank == rank Nw_local, npw, npw1 = chi0_wGG.shape assert npw == npw1 Nw = Nw_local * size if rank == 0: w = open(filename, 'w', comm) w.dimension('Nw', Nw) w.dimension('npw', npw) w.add(name, ('Nw', 'npw', 'npw'), dtype=complex) tmp = np.zeros_like(chi0_wGG[0]) for iw in range(Nw): irank = iw // Nw_local if irank == 0: if rank == 0: w.fill(chi0_wGG[iw]) else: if rank == irank: world.send(chi0_wGG[iw - rank * Nw_local], 0, irank + 100) if rank == 0: world.receive(tmp, irank, irank + 100) w.fill(tmp) if rank == 0: w.close() world.barrier()
def par_save(self,filename, name, A_sS): from gpaw.io import open nS_local = self.nS_local nS = self.nS if rank == 0: w = open(filename, 'w', world) w.dimension('nS', nS) if name == 'v_SS': w.add('w_S', ('nS',), dtype=self.w_S.dtype) w.fill(self.w_S) w.add('rhoG0_S', ('nS',), dtype=complex) w.fill(self.rhoG0_S) w.add(name, ('nS', 'nS'), dtype=complex) tmp = np.zeros_like(A_sS) # Assumes that H_SS is written in order from rank 0 - rank N for irank in range(size): if irank == 0: if rank == 0: w.fill(A_sS) else: if rank == irank: world.send(A_sS, 0, irank+100) if rank == 0: world.receive(tmp, irank, irank+100) w.fill(tmp) if rank == 0: w.close() world.barrier()
def dump_hamiltonian(filename, atoms, direction=None, Ef=None): h_skmm, s_kmm = get_hamiltonian(atoms) if direction is not None: d = 'xyz'.index(direction) for s in range(atoms.calc.nspins): for k in range(atoms.calc.nkpts): if s==0: remove_pbc(atoms, h_skmm[s, k], s_kmm[k], d) else: remove_pbc(atoms, h_skmm[s, k], None, d) if atoms.calc.master: fd = file(filename,'wb') pickle.dump((h_skmm, s_kmm), fd, 2) atoms_data = {'cell':atoms.cell, 'positions':atoms.positions, 'numbers':atoms.numbers, 'pbc':atoms.pbc} pickle.dump(atoms_data, fd, 2) calc_data ={'weight_k':atoms.calc.weight_k, 'ibzk_kc':atoms.calc.ibzk_kc} pickle.dump(calc_data, fd, 2) fd.close() world.barrier()
def get_e_h_density(self, lamda=None, filename=None): if filename is not None: self.load(filename) self.initialize() gd = self.gd w_S = self.w_S v_SS = self.v_SS A_S = v_SS[:, lamda] kq_k = self.kq_k kd = self.kd # Electron density nte_R = gd.zeros() for iS in range(self.nS_start, self.nS_end): print 'electron density:', iS k1, n1, m1 = self.Sindex_S3[iS] ibzkpt1 = kd.kibz_k[k1] psitold_g = self.get_wavefunction(ibzkpt1, n1) psit1_g = kd.transform_wave_function(psitold_g, k1) for jS in range(self.nS): k2, n2, m2 = self.Sindex_S3[jS] if m1 == m2 and k1 == k2: psitold_g = self.get_wavefunction(ibzkpt1, n2) psit2_g = kd.transform_wave_function(psitold_g, k1) nte_R += A_S[iS] * A_S[jS].conj() * psit1_g.conj() * psit2_g # Hole density nth_R = gd.zeros() for iS in range(self.nS_start, self.nS_end): print 'hole density:', iS k1, n1, m1 = self.Sindex_S3[iS] ibzkpt1 = kd.kibz_k[kq_k[k1]] psitold_g = self.get_wavefunction(ibzkpt1, m1) psit1_g = kd.transform_wave_function(psitold_g, kq_k[k1]) for jS in range(self.nS): k2, n2, m2 = self.Sindex_S3[jS] if n1 == n2 and k1 == k2: psitold_g = self.get_wavefunction(ibzkpt1, m2) psit2_g = kd.transform_wave_function(psitold_g, kq_k[k1]) nth_R += A_S[iS] * A_S[jS].conj() * psit1_g * psit2_g.conj() self.Scomm.sum(nte_R) self.Scomm.sum(nth_R) if rank == 0: write('rho_e.cube',self.calc.atoms, format='cube', data=nte_R) write('rho_h.cube',self.calc.atoms, format='cube', data=nth_R) world.barrier() return
def get_e_h_density(self, lamda=None, filename=None): if filename is not None: self.load(filename) self.initialize() gd = self.gd v_SS = self.v_SS A_S = v_SS[:, lamda] kq_k = self.kq_k kd = self.kd # Electron density nte_R = gd.zeros() for iS in range(self.nS_start, self.nS_end): print('electron density:', iS) k1, n1, m1 = self.Sindex_S3[iS] ibzkpt1 = kd.bz2ibz_k[k1] psitold_g = self.get_wavefunction(ibzkpt1, n1) psit1_g = kd.transform_wave_function(psitold_g, k1) for jS in range(self.nS): k2, n2, m2 = self.Sindex_S3[jS] if m1 == m2 and k1 == k2: psitold_g = self.get_wavefunction(ibzkpt1, n2) psit2_g = kd.transform_wave_function(psitold_g, k1) nte_R += A_S[iS] * A_S[jS].conj() * psit1_g.conj( ) * psit2_g # Hole density nth_R = gd.zeros() for iS in range(self.nS_start, self.nS_end): print('hole density:', iS) k1, n1, m1 = self.Sindex_S3[iS] ibzkpt1 = kd.bz2ibz_k[kq_k[k1]] psitold_g = self.get_wavefunction(ibzkpt1, m1) psit1_g = kd.transform_wave_function(psitold_g, kq_k[k1]) for jS in range(self.nS): k2, n2, m2 = self.Sindex_S3[jS] if n1 == n2 and k1 == k2: psitold_g = self.get_wavefunction(ibzkpt1, m2) psit2_g = kd.transform_wave_function(psitold_g, kq_k[k1]) nth_R += A_S[iS] * A_S[jS].conj() * psit1_g * psit2_g.conj( ) self.Scomm.sum(nte_R) self.Scomm.sum(nth_R) if rank == 0: write('rho_e.cube', self.calc.atoms, format='cube', data=nte_R) write('rho_h.cube', self.calc.atoms, format='cube', data=nth_R) world.barrier() return
def par_save(self, filename, name, A_sS): from gpaw.io import open nS = self.nS if rank == 0: w = open(filename, 'w', world) w.dimension('nS', nS) if name == 'v_SS': w.add('w_S', ('nS', ), dtype=self.w_S.dtype) w.fill(self.w_S) w.add('rhoG0_S', ('nS', ), dtype=complex) w.fill(self.rhoG0_S) w.add(name, ('nS', 'nS'), dtype=complex) tmp = np.zeros_like(A_sS) # Assumes that H_SS is written in order from rank 0 - rank N for irank in range(size): if irank == 0: if rank == 0: w.fill(A_sS) else: if rank == irank: world.send(A_sS, 0, irank + 100) if rank == 0: world.receive(tmp, irank, irank + 100) w.fill(tmp) if rank == 0: w.close() world.barrier()
def par_write(filename, name, comm, chi0_wGG): ## support only world communicator at the moment from gpaw.mpi import rank, size, world from gpaw.io import open assert comm.size == size assert comm.rank == rank Nw_local, npw, npw1 = chi0_wGG.shape assert npw == npw1 Nw = Nw_local * size w = open(filename, 'w', comm) w.dimension('Nw', Nw) w.dimension('npw', npw) w.add(name, ('Nw', 'npw', 'npw'), dtype=complex) if rank == 0: tmp = np.zeros_like(chi0_wGG[0]) for iw in range(Nw): irank = iw // Nw_local if irank == 0: if rank == 0: w.fill(chi0_wGG[iw]) else: if rank == irank: world.send(chi0_wGG[iw-rank*Nw_local], 0, irank+100) if rank == 0: world.receive(tmp, irank, irank+100) w.fill(tmp) if rank == 0: w.close() world.barrier()
def check_df(name, ref_energy, ref_loss, ref_energy_lfe, ref_loss_lfe, **kwargs_override): kwargs = dict(calc=calc, frequencies=w.copy(), eta=0.5, ecut=30, txt="df.%s.txt" % name) kwargs.update(kwargs_override) df = DielectricFunction(**kwargs) fname = "dfdump.%s.dat" % name df.get_eels_spectrum("RPA", q_c=q, filename=fname) world.barrier() d = np.loadtxt(fname, delimiter=",") loss = d[:, 1] loss_lfe = d[:, 2] energies = d[:, 0] # import pylab as pl # fig = pl.figure() # ax1 = fig.add_subplot(111) # ax1.plot(d[:, 0], d[:, 1]/np.max(d[:, 1])) # ax1.plot(d[:, 0], d[:, 2]/np.max(d[:, 2])) # ax1.axis(ymin=0, ymax=1) # fig.savefig('fig.%s.pdf' % name) energy, peakloss = getpeak(energies, loss) energy_lfe, peakloss_lfe = getpeak(energies, loss_lfe) check(name, energy, peakloss, ref_energy, ref_loss) check("%s-lfe" % name, energy_lfe, peakloss_lfe, ref_energy_lfe, ref_loss_lfe) line = template % (name, energy, peakloss, energy_lfe, peakloss_lfe, repr(kwargs_override)) scriptlines.append(line)
def _test_timestepping(self, t): #XXX DEBUG START if debug and os.path.isfile('%s_%d.gpw' % (self.tdname, t)): return #XXX DEBUG END timestep = self.timesteps[t] self.assertAlmostEqual(self.duration % timestep, 0.0, 12) niter = int(self.duration / timestep) ndiv = 1 #XXX traj = PickleTrajectory('%s_%d.traj' % (self.tdname, t), 'w', self.tdcalc.get_atoms()) t0 = time.time() f = paropen('%s_%d.log' % (self.tdname, t), 'w') print >>f, 'propagator: %s, duration: %6.1f as, timestep: %5.2f as, ' \ 'niter: %d' % (self.propagator, self.duration, timestep, niter) for i in range(1, niter+1): # XXX bare bones propagation without all the nonsense self.tdcalc.propagator.propagate(self.tdcalc.time, timestep * attosec_to_autime) self.tdcalc.time += timestep * attosec_to_autime self.tdcalc.niter += 1 if i % ndiv == 0: rate = 60 * ndiv / (time.time()-t0) ekin = self.tdcalc.atoms.get_kinetic_energy() epot = self.tdcalc.get_td_energy() * Hartree F_av = np.zeros((len(self.tdcalc.atoms), 3)) print >>f, 'i=%06d, time=%6.1f as, rate=%6.2f min^-1, ' \ 'ekin=%13.9f eV, epot=%13.9f eV, etot=%13.9f eV' \ % (i, timestep * i, rate, ekin, epot, ekin + epot) t0 = time.time() # Hack to prevent calls to GPAW::get_potential_energy when saving spa = self.tdcalc.get_atoms() spc = SinglePointCalculator(epot, F_av, None, None, spa) spa.set_calculator(spc) traj.write(spa) f.close() traj.close() self.tdcalc.write('%s_%d.gpw' % (self.tdname, t), mode='all') # Save density and wavefunctions to binary gd, finegd = self.tdcalc.wfs.gd, self.tdcalc.density.finegd if world.rank == 0: big_nt_g = finegd.collect(self.tdcalc.density.nt_g) np.save('%s_%d_nt.npy' % (self.tdname, t), big_nt_g) del big_nt_g big_psit_nG = gd.collect(self.tdcalc.wfs.kpt_u[0].psit_nG) np.save('%s_%d_psit.npy' % (self.tdname, t), big_psit_nG) del big_psit_nG else: finegd.collect(self.tdcalc.density.nt_g) gd.collect(self.tdcalc.wfs.kpt_u[0].psit_nG) world.barrier()
def _test_timestepping(self, t): #XXX DEBUG START if debug and os.path.isfile('%s_%d.gpw' % (self.tdname, t)): return #XXX DEBUG END timestep = self.timesteps[t] self.assertAlmostEqual(self.duration % timestep, 0.0, 12) niter = int(self.duration / timestep) ndiv = 1 #XXX traj = PickleTrajectory('%s_%d.traj' % (self.tdname, t), 'w', self.tdcalc.get_atoms()) t0 = time.time() f = paropen('%s_%d.log' % (self.tdname, t), 'w') print('propagator: %s, duration: %6.1f as, timestep: %5.2f as, ' \ 'niter: %d' % (self.propagator, self.duration, timestep, niter), file=f) for i in range(1, niter + 1): # XXX bare bones propagation without all the nonsense self.tdcalc.propagator.propagate(self.tdcalc.time, timestep * attosec_to_autime) self.tdcalc.time += timestep * attosec_to_autime self.tdcalc.niter += 1 if i % ndiv == 0: rate = 60 * ndiv / (time.time() - t0) ekin = self.tdcalc.atoms.get_kinetic_energy() epot = self.tdcalc.get_td_energy() * Hartree F_av = np.zeros((len(self.tdcalc.atoms), 3)) print('i=%06d, time=%6.1f as, rate=%6.2f min^-1, ' \ 'ekin=%13.9f eV, epot=%13.9f eV, etot=%13.9f eV' \ % (i, timestep * i, rate, ekin, epot, ekin + epot), file=f) t0 = time.time() # Hack to prevent calls to GPAW::get_potential_energy when saving spa = self.tdcalc.get_atoms() spc = SinglePointCalculator(epot, F_av, None, None, spa) spa.set_calculator(spc) traj.write(spa) f.close() traj.close() self.tdcalc.write('%s_%d.gpw' % (self.tdname, t), mode='all') # Save density and wavefunctions to binary gd, finegd = self.tdcalc.wfs.gd, self.tdcalc.density.finegd if world.rank == 0: big_nt_g = finegd.collect(self.tdcalc.density.nt_g) np.save('%s_%d_nt.npy' % (self.tdname, t), big_nt_g) del big_nt_g big_psit_nG = gd.collect(self.tdcalc.wfs.kpt_u[0].psit_nG) np.save('%s_%d_psit.npy' % (self.tdname, t), big_psit_nG) del big_psit_nG else: finegd.collect(self.tdcalc.density.nt_g) gd.collect(self.tdcalc.wfs.kpt_u[0].psit_nG) world.barrier()
def record_memory(wait=0.1): assert gc.collect() == 0, 'Uncollected garbage!' world.barrier() time.sleep(wait) mem = MemoryStatistics() time.sleep(wait) world.barrier() return mem
def arrange_analysis_data(self, n_bias_step, n_ion_step, analysis_mode): data = self.read_data(bias_step=n_bias_step, option='Analysis') parsize = data['domain_parsize'] parpos = data['domain_parpos'] domain_rank = data['domain_rank'] kpt_rank = data['kpt_rank'] kpt_size = data['kpt_size'] transmission_dimension = data['transmission_dimension'] dos_dimension = data['dos_dimension'] assert kpt_rank == self.kpt_comm.rank assert domain_rank == self.domain_comm.rank #collect transmission, dos, current global_data = {} flag = 'K_' + str(kpt_rank) + 'D_' + str(domain_rank) + '_' global_data[flag + 'parpos'] = data['domain_parpos'] global_data[flag + 'tc'] = data['tc'] global_data[flag + 'dos'] = data['dos'] global_data = gather_ndarray_dict(global_data, self.kpt_comm) global_data[flag + 'vt'] = data['vt'] global_data[flag + 'vtx'] = data['vtx'] global_data[flag + 'vty'] = data['vty'] global_data[flag + 'nt'] = data['nt'] global_data[flag + 'ntx'] = data['ntx'] global_data[flag + 'nty'] = data['nty'] global_data = gather_ndarray_dict(global_data, self.domain_comm) global_data['lead_fermi'] = data['lead_fermi'] global_data['bias'] = data['bias'] global_data['gate'] = data['gate'] global_data['charge'] = data['charge'] global_data['magmom'] = data['magmom'] global_data['local_magmom'] = data['local_magmom'] global_data['newform'] = True global_data['domain_parsize'] = data['domain_parsize'] global_data['kpt_size'] = data['kpt_size'] global_data['transmission_dimension'] = data['transmission_dimension'] global_data['dos_dimension'] = data['dos_dimension'] world.barrier() if world.rank == 0: if analysis_mode: filename = '/abias_step_' + str(n_bias_step) else: filename = '/bias_step_' + str(n_bias_step) fd = file('analysis_data/ionic_step_' + str(n_ion_step) + filename, 'wb') cPickle.dump(global_data, fd, 2) fd.close() for root, dirs, files in os.walk('temperary_data'): for name in files: if 'AD' in name: os.remove(os.path.join(root, name))
def save(self, filename): """Dump essential data""" data = {'w_S': self.w_S, 'v_SS': self.v_SS} if rank == 0: pickle.dump(data, open(filename, 'w'), -1) world.barrier()
def get_combined_data(self, qmdata=None, cldata=None, spacing=None): if qmdata is None: qmdata = self.density.rhot_g if cldata is None: cldata = self.classical_material.charge_density if spacing is None: spacing = self.cl.gd.h_cv[0, 0] spacing_au = spacing / Bohr # from Angstroms to a.u. # Collect data from different processes cln = self.cl.gd.collect(cldata) qmn = self.qm.gd.collect(qmdata) clgd = GridDescriptor(self.cl.gd.N_c, self.cl.cell, False, serial_comm, None) if world.rank == 0: cln *= self.classical_material.sign # refine classical part while clgd.h_cv[0, 0] > spacing_au * 1.50: # 45: cln = Transformer(clgd, clgd.refine()).apply(cln) clgd = clgd.refine() # refine quantum part qmgd = GridDescriptor(self.qm.gd.N_c, self.qm.cell, False, serial_comm, None) while qmgd.h_cv[0, 0] < clgd.h_cv[0, 0] * 0.95: qmn = Transformer(qmgd, qmgd.coarsen()).apply(qmn) qmgd = qmgd.coarsen() assert np.all(qmgd.h_cv == clgd.h_cv), " Spacings %.8f (qm) and %.8f (cl) Angstroms" % (qmgd.h_cv[0][0] * Bohr, clgd.h_cv[0][0] * Bohr) # now find the corners r_gv_cl = clgd.get_grid_point_coordinates().transpose((1, 2, 3, 0)) cind = self.qm.corner1 / np.diag(clgd.h_cv) - 1 n = qmn.shape # print 'Corner points: ', self.qm.corner1*Bohr, ' - ', self.qm.corner2*Bohr # print 'Calculated points: ', r_gv_cl[tuple(cind)]*Bohr, ' - ', r_gv_cl[tuple(cind+n+1)]*Bohr cln[cind[0] + 1:cind[0] + n[0] + 1, cind[1] + 1:cind[1] + n[1] + 1, cind[2] + 1:cind[2] + n[2] + 1] += qmn world.barrier() return cln, clgd
def get_excitation_wavefunction(self, lamda=None,filename=None, re_c=None, rh_c=None): if filename is not None: self.load(filename) self.initialize() gd = self.gd w_S = self.w_S v_SS = self.v_SS A_S = v_SS[:, lamda] kq_k = self.kq_k kd = self.kd if re_c is not None: psith_R = gd.zeros(dtype=complex) elif rh_c is not None: psite_R = gd.zeros(dtype=complex) else: self.printtxt('No wavefunction output !') return for iS in range(self.nS_start, self.nS_end): print 'hole wavefunction', iS k, n, m = self.Sindex_S3[iS] ibzkpt1 = kd.kibz_k[k] ibzkpt2 = kd.kibz_k[kq_k[k]] psitold_g = self.get_wavefunction(ibzkpt1, n) psit1_g = kd.transform_wave_function(psitold_g, k) psitold_g = self.get_wavefunction(ibzkpt2, m) psit2_g = kd.transform_wave_function(psitold_g, kq_k[k]) if re_c is not None: # given electron position, plot hole wavefunction psith_R += A_S[iS] * psit1_g[re_c].conj() * psit2_g elif rh_c is not None: # given hole position, plot electron wavefunction psite_R += A_S[iS] * psit1_g.conj() * psit2_g[rh_c] else: pass if re_c is not None: self.Scomm.sum(psith_R) if rank == 0: write('psit_h.cube',self.calc.atoms, format='cube', data=psith_R) elif rh_c is not None: self.Scomm.sum(psite_R) if rank == 0: write('psit_e.cube',self.calc.atoms, format='cube', data=psite_R) else: pass world.barrier() return
def save(self, filename): """Dump essential data""" data = {'w_S' : self.w_S, 'v_SS' : self.v_SS} if rank == 0: pickle.dump(data, open(filename, 'w'), -1) world.barrier()
def __init__(self, kpt_comm, domain_comm): self.kpt_comm = kpt_comm self.domain_comm = domain_comm assert self.kpt_comm.size * self.domain_comm.size == world.size self.dir_name = 'temperary_data' if world.rank == 0: if not os.access(self.dir_name, os.F_OK): os.mkdir(self.dir_name) world.barrier() self.filenames = self.default_temperary_filenames()
def main(): from gpaw.grid_descriptor import GridDescriptor from gpaw.mpi import world serial = world.new_communicator([world.rank]) # Generator which must run on all ranks gen = np.random.RandomState(0) # This one is just used by master gen_serial = np.random.RandomState(17) maxsize = 5 for i in range(1): N1_c = gen.randint(1, maxsize, 3) N2_c = gen.randint(1, maxsize, 3) gd1 = GridDescriptor(N1_c, N1_c) gd2 = GridDescriptor(N2_c, N2_c) serial_gd1 = gd1.new_descriptor(comm=serial) serial_gd2 = gd2.new_descriptor(comm=serial) a1_serial = serial_gd1.empty() a1_serial.flat[:] = gen_serial.rand(a1_serial.size) if world.rank == 0: print('r0: a1 serial', a1_serial.ravel()) a1 = gd1.empty() a1[:] = -1 grid2grid(world, serial_gd1, gd1, a1_serial, a1) print(world.rank, 'a1 distributed', a1.ravel()) world.barrier() a2 = gd2.zeros() a2[:] = -2 grid2grid(world, gd1, gd2, a1, a2) print(world.rank, 'a2 distributed', a2.ravel()) world.barrier() #grid2grid(world, gd2, gd2_serial gd1 = GridDescriptor(N1_c, N1_c * 0.2) #serialgd = gd2.new_descriptor( a1 = gd1.empty() a1.flat[:] = gen.rand(a1.size) #print a1 grid2grid(world, gd1, gd2, a1, a2)
def get_combined_data(self, qmdata=None, cldata=None, spacing=None): if qmdata is None: qmdata = self.density.rhot_g if cldata is None: cldata = self.classical_material.charge_density if spacing is None: spacing = self.cl.gd.h_cv[0, 0] spacing_au = spacing / Bohr # from Angstroms to a.u. # Collect data from different processes cln = self.cl.gd.collect(cldata) qmn = self.qm.gd.collect(qmdata) clgd = GridDescriptor(self.cl.gd.N_c, self.cl.cell, False, serial_comm, None) if world.rank == 0: cln *= self.classical_material.sign # refine classical part while clgd.h_cv[0, 0] > spacing_au * 1.50: # 45: cln = Transformer(clgd, clgd.refine()).apply(cln) clgd = clgd.refine() # refine quantum part qmgd = GridDescriptor(self.qm.gd.N_c, self.qm.cell, False, serial_comm, None) while qmgd.h_cv[0, 0] < clgd.h_cv[0, 0] * 0.95: qmn = Transformer(qmgd, qmgd.coarsen()).apply(qmn) qmgd = qmgd.coarsen() assert np.all(qmgd.h_cv == clgd.h_cv ), " Spacings %.8f (qm) and %.8f (cl) Angstroms" % ( qmgd.h_cv[0][0] * Bohr, clgd.h_cv[0][0] * Bohr) # now find the corners r_gv_cl = clgd.get_grid_point_coordinates().transpose((1, 2, 3, 0)) cind = self.qm.corner1 / np.diag(clgd.h_cv) - 1 n = qmn.shape # print 'Corner points: ', self.qm.corner1*Bohr, ' - ', self.qm.corner2*Bohr # print 'Calculated points: ', r_gv_cl[tuple(cind)]*Bohr, ' - ', r_gv_cl[tuple(cind+n+1)]*Bohr cln[cind[0] + 1:cind[0] + n[0] + 1, cind[1] + 1:cind[1] + n[1] + 1, cind[2] + 1:cind[2] + n[2] + 1] += qmn world.barrier() return cln, clgd
def save_ion_step(self, tp): if world.rank == 0: fd = file('analysis_data/ionic_step_' + str(self.n_ion_step) +'/positions', 'wb') cPickle.dump(tp.atoms.positions, fd, 2) fd.close() self.n_bias_step = 0 self.n_ion_step += 1 if world.rank == 0: dirname = 'analysis_data/ionic_step_' + str(self.n_ion_step) if not os.access(dirname, os.F_OK): os.mkdir(dirname) world.barrier()
def __init__(self, particle, dyn, name, fmt='-%04i.pickle', directory=None): self.dyn = dyn self.particle = particle if directory is None: directory = '' else: if not directory.endswith('/'): directory += '/' if not os.path.isdir(directory): if world.rank == MASTER: os.mkdir(directory) world.barrier() self.fmt = directory + name + fmt
def save_ion_step(self, tp): if world.rank == 0: fd = file( 'analysis_data/ionic_step_' + str(self.n_ion_step) + '/positions', 'wb') cPickle.dump(tp.atoms.positions, fd, 2) fd.close() self.n_bias_step = 0 self.n_ion_step += 1 if world.rank == 0: dirname = 'analysis_data/ionic_step_' + str(self.n_ion_step) if not os.access(dirname, os.F_OK): os.mkdir(dirname) world.barrier()
def get_dielectric_function(self, filename='df.dat'): if self.epsilon_w is None: self.initialize() self.calculate() w_S = self.w_S v_SS = self.v_SS rhoG0_S = self.rhoG0_S focc_S = self.focc_S # get overlap matrix tmp = np.zeros((self.nS, self.nS), dtype=complex) for iS in range(self.nS): for jS in range(self.nS): tmp[iS, jS] = (v_SS[:, iS].conj() * v_SS[:, jS]).sum() overlap_SS = np.linalg.inv(tmp) # get chi epsilon_w = np.zeros(self.Nw, dtype=complex) tmp_w = np.zeros(self.Nw, dtype=complex) for iS in range(self.nS_start, self.nS_end): tmp_iS = v_SS[:, iS] * rhoG0_S for iw in range(self.Nw): tmp_w[iw] = 1. / (iw * self.dw - w_S[iS] + 1j * self.eta) print 'calculating epsilon', iS for jS in range(self.nS): tmp_jS = v_SS[:, jS] * rhoG0_S * focc_S tmp = np.outer(tmp_iS, tmp_jS.conj()).sum() * overlap_SS[iS, jS] epsilon_w += tmp * tmp_w self.Scomm.sum(epsilon_w) epsilon_w *= -4 * pi / np.inner(self.qq_v, self.qq_v) / self.vol epsilon_w += 1 self.epsilon_w = epsilon_w if rank == 0: f = open(filename, 'w') for iw in range(self.Nw): energy = iw * self.dw * Hartree print >> f, energy, np.real(epsilon_w[iw]), np.imag( epsilon_w[iw]) f.close() # Wait for I/O to finish world.barrier() return
def get_polarization_phase(calc): assert isinstance(calc, str) name = splitext(calc)[0] berryname = '{}-berryphases.json'.format(name) phase_c = np.zeros((3, ), float) if not exists(berryname) and world.rank == 0: # Calculate and save berry phases calc = GPAW(calc, communicator=serial_comm, txt=None) nspins = calc.wfs.nspins data = {} for c in [0, 1, 2]: data[c] = {} for spin in range(nspins): indices_kk, phases = get_berry_phases(calc, dir=c, spin=spin) data[c][spin] = phases # Ionic contribution Z_a = [] for num in calc.atoms.get_atomic_numbers(): for ida, setup in zip(calc.wfs.setups.id_a, calc.wfs.setups): if abs(ida[0] - num) < 1e-5: break Z_a.append(setup.Nv) data['Z_a'] = Z_a data['spos_ac'] = calc.spos_ac.tolist() with open(berryname, 'w') as fd: json.dump(data, fd, indent=True) world.barrier() # Read data and calculate phase if world.rank == 0: print('Reading berryphases {}'.format(berryname)) with open(berryname) as fd: data = json.load(fd) for c in [0, 1, 2]: nspins = len(data[str(c)]) for spin in range(nspins): phases = data[str(c)][str(spin)] phase_c[c] += np.sum(phases) / len(phases) phase_c = phase_c * 2 / nspins Z_a = data['Z_a'] spos_ac = data['spos_ac'] phase_c += 2 * np.pi * np.dot(Z_a, spos_ac) return phase_c
def get_dielectric_function(self, filename='df.dat'): if self.epsilon_w is None: self.initialize() self.calculate() w_S = self.w_S v_SS = self.v_SS rhoG0_S = self.rhoG0_S focc_S = self.focc_S # get overlap matrix tmp = np.zeros((self.nS, self.nS), dtype=complex) for iS in range(self.nS): for jS in range(self.nS): tmp[iS, jS] = (v_SS[:, iS].conj() * v_SS[:, jS]).sum() overlap_SS = np.linalg.inv(tmp) # get chi epsilon_w = np.zeros(self.Nw, dtype=complex) tmp_w = np.zeros(self.Nw, dtype=complex) for iS in range(self.nS_start, self.nS_end): tmp_iS = v_SS[:,iS] * rhoG0_S for iw in range(self.Nw): tmp_w[iw] = 1. / (iw*self.dw - w_S[iS] + 1j * self.eta) print 'calculating epsilon', iS for jS in range(self.nS): tmp_jS = v_SS[:,jS] * rhoG0_S * focc_S tmp = np.outer(tmp_iS, tmp_jS.conj()).sum() * overlap_SS[iS, jS] epsilon_w += tmp * tmp_w self.Scomm.sum(epsilon_w) epsilon_w *= - 4 * pi / np.inner(self.qq_v, self.qq_v) / self.vol epsilon_w += 1 self.epsilon_w = epsilon_w if rank == 0: f = open(filename,'w') for iw in range(self.Nw): energy = iw * self.dw * Hartree print >> f, energy, np.real(epsilon_w[iw]), np.imag(epsilon_w[iw]) f.close() # Wait for I/O to finish world.barrier() return
def collect_A_SS(self, A_sS): if world.rank == 0: A_SS = np.zeros((self.nS, self.nS), dtype=complex) A_SS[:len(A_sS)] = A_sS Ntot = len(A_sS) for rank in range(1, world.size): nkr, nk, ns = self.parallelisation_sizes(rank) buf = np.empty((ns, self.nS), dtype=complex) world.receive(buf, rank, tag=123) A_SS[Ntot:Ntot + ns] = buf Ntot += ns else: world.send(A_sS, 0, tag=123) world.barrier() if world.rank == 0: return A_SS
def main(nbands=1000, mprocs=2, mb=64): # Set-up BlacsGrud grid = BlacsGrid(world, mprocs, mprocs) # Create descriptor nndesc = grid.new_descriptor(nbands, nbands, mb, mb) H_nn = nndesc.empty( dtype=float) # outside the BlacsGrid these are size zero C_nn = nndesc.empty( dtype=float) # outside the BlacsGrid these are size zero eps_N = np.empty((nbands), dtype=float) # replicated array on all MPI tasks # Fill ScaLAPACK array alpha = 0.1 # off-diagonal beta = 75.0 # diagonal uplo = 'L' # lower-triangular scalapack_set(nndesc, H_nn, alpha, beta, uplo) scalapack_zero(nndesc, H_nn, switch_uplo[uplo]) t1 = time() # either interface will work, we recommend use the latter interface # scalapack_diagonalize_dc(nndesc, H_nn.copy(), C_nn, eps_N, 'L') nndesc.diagonalize_dc(H_nn.copy(), C_nn, eps_N) t2 = time() world.broadcast(eps_N, 0) # all MPI tasks now have eps_N world.barrier() # wait for everyone to finish if rank == 0: print('ScaLAPACK diagonalize_dc', t2 - t1) # Create replicated NumPy array diagonal = np.eye(nbands, dtype=float) offdiagonal = np.tril(np.ones((nbands, nbands)), -1) H0 = beta * diagonal + alpha * offdiagonal E0 = np.empty((nbands), dtype=float) t1 = time() diagonalize(H0, E0) t2 = time() if rank == 0: print('LAPACK diagonalize', t2 - t1) delta = abs(E0 - eps_N).max() if rank == 0: print(delta) assert delta < tol
def get_dielectric_function(self, w_w=None, eta=0.1, q_c=[0.0, 0.0, 0.0], direction=0, filename='df_bse.csv', readfile=None, write_eig='eig.dat'): """Returns and writes real and imaginary part of the dielectric function. w_w: list of frequencies (eV) Dielectric function is calculated at these frequencies eta: float Lorentzian broadening of the spectrum (eV) q_c: list of three floats Wavevector in reduced units on which the response is calculated direction: int if q_c = [0, 0, 0] this gives the direction in cartesian coordinates - 0=x, 1=y, 2=z filename: str data file on which frequencies, real and imaginary part of dielectric function is written readfile: str If H_SS is given, the method will load the BSE Hamiltonian from H_SS.ulm. If v_TS is given, the method will load the eigenstates from v_TS.ulm write_eig: str File on which the BSE eigenvalues are written """ epsilon_w = -self.get_vchi(w_w=w_w, eta=eta, q_c=q_c, direction=direction, readfile=readfile, optical=True, write_eig=write_eig) epsilon_w += 1.0 if world.rank == 0 and filename is not None: f = open(filename, 'w') for iw, w in enumerate(w_w): print('%.9f, %.9f, %.9f' % (w, epsilon_w[iw].real, epsilon_w[iw].imag), file=f) f.close() world.barrier() print('Calculation completed at:', ctime(), file=self.fd) print(file=self.fd) return w_w, epsilon_w
def distribute_A_SS(self, A_SS, transpose=False): if world.rank == 0: for rank in range(0, world.size): nkr, nk, ns = self.parallelisation_sizes(rank) if rank == 0: A_sS = A_SS[0:ns] Ntot = ns else: world.send(A_SS[Ntot:Ntot + ns], rank, tag=123) Ntot += ns else: nkr, nk, ns = self.parallelisation_sizes() A_sS = np.empty((ns, self.nS), dtype=complex) world.receive(A_sS, 0, tag=123) world.barrier() if transpose: A_sS = A_sS.T return A_sS
def par_save(self, filename, name, A_sS): import ase.io.ulm as ulm if world.size == 1: A_XS = A_sS else: A_XS = self.collect_A_SS(A_sS) if world.rank == 0: w = ulm.open(filename, 'w') if name == 'v_TS': w.write(w_T=self.w_T) # w.write(nS=self.nS) w.write(rhoG0_S=self.rhoG0_S) w.write(df_S=self.df_S) w.write(A_XS=A_XS) w.close() world.barrier()
def main(nbands=1000, mprocs=2, mb=64): # Set-up BlacsGrud grid = BlacsGrid(world, mprocs, mprocs) # Create descriptor nndesc = grid.new_descriptor(nbands, nbands, mb, mb) H_nn = nndesc.empty(dtype=float) # outside the BlacsGrid these are size zero C_nn = nndesc.empty(dtype=float) # outside the BlacsGrid these are size zero eps_N = np.empty((nbands), dtype=float) # replicated array on all MPI tasks # Fill ScaLAPACK array alpha = 0.1 # off-diagonal beta = 75.0 # diagonal uplo = 'L' # lower-triangular scalapack_set(nndesc, H_nn, alpha, beta, uplo) scalapack_zero(nndesc, H_nn, switch_uplo[uplo]) t1 = time() # either interface will work, we recommend use the latter interface # scalapack_diagonalize_dc(nndesc, H_nn.copy(), C_nn, eps_N, 'L') nndesc.diagonalize_dc(H_nn.copy(), C_nn, eps_N) t2 = time() world.broadcast(eps_N, 0) # all MPI tasks now have eps_N world.barrier() # wait for everyone to finish if rank == 0: print('ScaLAPACK diagonalize_dc', t2-t1) # Create replicated NumPy array diagonal = np.eye(nbands,dtype=float) offdiagonal = np.tril(np.ones((nbands,nbands)), -1) H0 = beta*diagonal + alpha*offdiagonal E0 = np.empty((nbands), dtype=float) t1 = time() diagonalize(H0,E0) t2 = time() if rank == 0: print('LAPACK diagonalize', t2-t1) delta = abs(E0-eps_N).max() if rank == 0: print(delta) assert delta < tol
def run(self): """Start calculation or read results from file.""" filename = '%s%s.traj' % (self.name, self.tag) if self.clean or not os.path.isfile(filename): world.barrier() if world.rank == 0: open(filename, 'w') self.calculate(filename) else: try: self.log('Reading', filename, end=' ') configs = read(filename, ':') except IOError: self.log('FAILED') else: self.log() if self.fmax is not None: configs = configs[-1:] # Extract bondlengths/volumes and energies: if self.dimer: self.bondlengths = [a.get_distance(0, 1) for a in configs] else: self.volumes = [a.get_volume() for a in configs] self.energies = [a.get_potential_energy() for a in configs]
def get_phi_qaGp(self): N1_max = 0 N2_max = 0 natoms = len(self.calc.wfs.setups) for id in range(natoms): N1 = self.npw N2 = self.calc.wfs.setups[id].ni**2 if N1 > N1_max: N1_max = N1 if N2 > N2_max: N2_max = N2 nbzq = self.kd.nbzkpts nbzq, nq_local, q_start, q_end = parallel_partition( nbzq, world.rank, world.size, reshape=False) phimax_qaGp = np.zeros((nq_local, natoms, N1_max, N2_max), dtype=complex) #phimax_qaGp = np.zeros((nbzq, natoms, N1_max, N2_max), dtype=complex) t0 = time() for iq in range(nq_local): q_c = self.bzq_qc[iq + q_start] tmp_aGp = self.get_phi_aGp(q_c, parallel=False) for id in range(natoms): N1, N2 = tmp_aGp[id].shape phimax_qaGp[iq, id, :N1, :N2] = tmp_aGp[id] self.timing(iq*world.size, t0, nq_local, 'iq') world.barrier() # Write to disk filename = 'phi_qaGp' if world.rank == 0: w = Writer(filename) w.dimension('nbzq', nbzq) w.dimension('natoms', natoms) w.dimension('nG', N1_max) w.dimension('nii', N2_max) w.add('phi_qaGp', ('nbzq', 'natoms', 'nG', 'nii',), dtype=complex) for q in range(nbzq): residual = nbzq % size N_local = nbzq // size if q < residual * (N_local + 1): qrank = q // (N_local + 1) else: qrank = (q - residual * (N_local + 1)) // N_local + residual if qrank == 0: if world.rank == 0: phi_aGp = phimax_qaGp[q - q_start] else: if world.rank == qrank: phi_aGp = phimax_qaGp[q - q_start] world.send(phi_aGp, 0, q) elif world.rank == 0: world.receive(phi_aGp, qrank, q) if world.rank == 0: w.fill(phi_aGp) world.barrier() if world.rank == 0: w.close() return
def initialize(self, tp): kw = tp.analysis_parameters if self.restart: self.initialize_selfenergy_and_green_function(tp) else: self.selfenergies = tp.selfenergies p = self.set_default_analysis_parameters() for key in kw: if key in [ 'energies', 'lead_pairs', 'dos_project_atoms', 'project_equal_atoms', 'project_molecular_levels', 'isolate_atoms', 'dos_project_orbital', 'trans_project_orbital', 'eig_trans_channel_energies', 'eig_trans_channel_num', 'dos_realspace_energies' ]: p[key] = kw[key] for key in p: vars(self)[key] = p[key] ef = tp.lead_fermi[0] path = tp.contour.get_plot_path() self.energies = path.energies self.my_energies = path.my_energies self.weights = path.weights self.my_weights = path.my_weights self.nids = path.nids self.my_nids = path.my_nids for variable in [ self.eig_trans_channel_energies, self.dos_realspace_energies ]: if variable is not None: variable = np.array(variable) + ef ecomm = tp.contour.comm if self.eig_trans_channel_energies is not None: self.my_eig_trans_channel_energies = np.array_split( self.eig_trans_channel_energies, ecomm.size)[ecomm.rank] self.my_eig_trans_channel_nids = np.array_split( np.arange(len(self.eig_trans_channel_energies)), ecomm.size)[ecomm.rank] if self.dos_realspace_energies is not None: self.my_dos_realspace_energies = np.array_split( self.dos_realspace_energies, ecomm.size)[ecomm.rank] self.my_dos_realspace_nids = np.array_split( np.arange(len(self.dos_realspace_energies)), ecomm.size)[ecomm.rank] setups = tp.inner_setups self.project_atoms_in_device = self.project_equal_atoms[0] self.project_atoms_in_molecule = self.project_equal_atoms[1] self.project_basis_in_device = get_atom_indices( self.project_atoms_in_device, setups) if self.isolate_atoms is not None: self.calculate_isolate_molecular_levels(tp) self.overhead_data_saved = False if world.rank == 0: if not os.access('analysis_data', os.F_OK): os.mkdir('analysis_data') if not os.access('analysis_data/ionic_step_0', os.F_OK): os.mkdir('analysis_data/ionic_step_0') world.barrier() self.data = {}
def get_dielectric_function(self, filename='df.dat', readfile=None): if self.epsilon_w is None: self.initialize() if readfile is None: H_sS = self.calculate() self.printtxt('Diagonalizing %s matrix.' % self.mode) self.diagonalize(H_sS) self.printtxt('Calculating dielectric function.') elif readfile == 'H_SS': H_sS = self.par_load('H_SS', 'H_SS') self.printtxt('Finished reading H_SS.gpw') self.diagonalize(H_sS) self.printtxt('Finished diagonalizing BSE matrix') elif readfile == 'v_SS': self.v_SS = self.par_load('v_SS', 'v_SS') self.printtxt('Finished reading v_SS.gpw') else: XX w_S = self.w_S if not self.coupling: v_SS = self.v_SS.T # v_SS[:,lamda] else: v_SS = self.v_SS rhoG0_S = self.rhoG0_S focc_S = self.focc_S # get overlap matrix if self.coupling: tmp = np.dot(v_SS.conj().T, v_SS ) overlap_SS = np.linalg.inv(tmp) # get chi epsilon_w = np.zeros(self.Nw, dtype=complex) t0 = time() A_S = np.dot(rhoG0_S, v_SS) B_S = np.dot(rhoG0_S*focc_S, v_SS) if self.coupling: C_S = np.dot(B_S.conj(), overlap_SS.T) * A_S else: if world.size == 1: C_S = B_S.conj() * A_S else: tmp = B_S.conj() * A_S C_S = gatherv(tmp, self.nS) for iw in range(self.Nw): tmp_S = 1. / (iw*self.dw - w_S + 1j*self.eta) epsilon_w[iw] += np.dot(tmp_S, C_S) epsilon_w *= - 4 * pi / np.inner(self.qq_v, self.qq_v) / self.vol epsilon_w += 1 self.epsilon_w = epsilon_w if rank == 0: f = open(filename,'w') #g = open('excitons.dat', 'w') for iw in range(self.Nw): energy = iw * self.dw * Hartree print >> f, energy, np.real(epsilon_w[iw]), np.imag(epsilon_w[iw]) #print >> g, energy, np.real(C_S[iw])/max(abs(C_S)) f.close() #g.close() # Wait for I/O to finish world.barrier() """Check f-sum rule.""" N1 = 0 for iw in range(self.Nw): w = iw * self.dw N1 += np.imag(epsilon_w[iw]) * w N1 *= self.dw * self.vol / (2 * pi**2) self.printtxt('') self.printtxt('Sum rule:') nv = self.nvalence self.printtxt('N1 = %f, %f %% error' %(N1, (N1 - nv) / nv * 100) ) return epsilon_w
def get_excitation_wavefunction(self, lamda=None,filename=None, re_c=None, rh_c=None): """ garbage at the moment. come back later""" if filename is not None: self.load(filename) self.initialize() gd = self.gd w_S = self.w_S v_SS = self.v_SS A_S = v_SS[:, lamda] kq_k = self.kq_k kd = self.kd nx, ny, nz = self.gd.N_c nR = 9 nR2 = (nR - 1 ) // 2 if re_c is not None: psith_R = gd.zeros(dtype=complex) psith2_R = np.zeros((nR*nx, nR*ny, nz), dtype=complex) elif rh_c is not None: psite_R = gd.zeros(dtype=complex) psite2_R = np.zeros((nR*nx, ny, nR*nz), dtype=complex) else: self.printtxt('No wavefunction output !') return for iS in range(self.nS_start, self.nS_end): k, n, m = self.Sindex_S3[iS] ibzkpt1 = kd.bz2ibz_k[k] ibzkpt2 = kd.bz2ibz_k[kq_k[k]] print 'hole wavefunction', iS, (k,n,m),A_S[iS] psitold_g = self.get_wavefunction(ibzkpt1, n) psit1_g = kd.transform_wave_function(psitold_g, k) psitold_g = self.get_wavefunction(ibzkpt2, m) psit2_g = kd.transform_wave_function(psitold_g, kq_k[k]) if re_c is not None: # given electron position, plot hole wavefunction tmp = A_S[iS] * psit1_g[re_c].conj() * psit2_g psith_R += tmp k_c = self.kd.bzk_kc[k] + self.q_c for i in range(nR): for j in range(nR): R_c = np.array([i-nR2, j-nR2, 0]) psith2_R[i*nx:(i+1)*nx, j*ny:(j+1)*ny, 0:nz] += \ tmp * np.exp(1j*2*pi*np.dot(k_c,R_c)) elif rh_c is not None: # given hole position, plot electron wavefunction tmp = A_S[iS] * psit1_g.conj() * psit2_g[rh_c] * self.expqr_g psite_R += tmp k_c = self.kd.bzk_kc[k] k_v = np.dot(k_c, self.bcell_cv) for i in range(nR): for j in range(nR): R_c = np.array([i-nR2, 0, j-nR2]) R_v = np.dot(R_c, self.acell_cv) assert np.abs(np.dot(k_v, R_v) - np.dot(k_c, R_c) * 2*pi).sum() < 1e-5 psite2_R[i*nx:(i+1)*nx, 0:ny, j*nz:(j+1)*nz] += \ tmp * np.exp(-1j*np.dot(k_v,R_v)) else: pass if re_c is not None: self.Scomm.sum(psith_R) self.Scomm.sum(psith2_R) if rank == 0: write('psit_h.cube',self.calc.atoms, format='cube', data=psith_R) atoms = self.calc.atoms shift = atoms.cell[0:2].copy() positions = atoms.positions atoms.cell[0:2] *= nR2 atoms.positions += shift * (nR2 - 1) write('psit_bigcell_h.cube',atoms, format='cube', data=psith2_R) elif rh_c is not None: self.Scomm.sum(psite_R) self.Scomm.sum(psite2_R) if rank == 0: write('psit_e.cube',self.calc.atoms, format='cube', data=psite_R) atoms = self.calc.atoms # shift = atoms.cell[0:2].copy() positions = atoms.positions atoms.cell[0:2] *= nR2 # atoms.positions += shift * (nR2 - 1) write('psit_bigcell_e.cube',atoms, format='cube', data=psite2_R) else: pass world.barrier() return
def calculate(element, ref_data, p): values_dict = {} values_dict[p['xc']] = {} for XY, data in ref_data[p['xc']].items(): X = XY.split('-')[0] Y = XY.split('-')[1] if (X == Y and X == element) or (X != Y and (X == element or Y == element)): # compound contains the requested element re_ref = data['re'] we_ref = data['we'] m0_ref = data.get('m0', 0.0) # compound = Atoms(X+Y, [ (0, 0, 0.5 ), (0, 0, 0.5+re_ref/a), ], pbc=0) compound.set_cell([a, b, c], scale_atoms=1) compound.center() # calculation on the reference geometry calc = Calculator(**p) compound.set_calculator(calc) e_compound = compound.get_potential_energy() finegd = calc.density.finegd dip = finegd.calculate_dipole_moment(calc.density.rhot_g)*calc.a0 vib = Vibrations(compound) vib.run() vib_compound = vib.get_frequencies(method='frederiksen').real[-1] world.barrier() vib_pckl = glob('vib.*.pckl') if rank == 0: for file in vib_pckl: remove(file) # calculation on the relaxed geometry qn = QuasiNewton(compound) #qn.attach(PickleTrajectory('compound.traj', 'w', compound).write) qn.run(fmax=0.05) e_compound_r = compound.get_potential_energy() dist_compound_r = compound.get_distance(0,1) dip_r = finegd.calculate_dipole_moment(calc.density.rhot_g)*calc.a0 vib = Vibrations(compound) vib.run() vib_compound_r = vib.get_frequencies(method='frederiksen').real[-1] world.barrier() vib_pckl = glob('vib.*.pckl') if rank == 0: for file in vib_pckl: remove(file) del compound e = e_compound we = vib_compound m0 = dip e_r = e_compound_r we_r = vib_compound_r re_r = dist_compound_r m0_r = dip_r # values_dict[p['xc']][XY] = {'re': re_r, 'we': (we_r, we), 'm0': (m0_r, m0)} # return values_dict
def get_QP_spectrum(self, exxfile='EXX.pckl', file='GW.pckl'): try: self.ini except: self.initialize() self.print_gw_init() self.printtxt("calculating Self energy") Sigma_skn = np.zeros((self.nspins, self.gwnkpt, self.gwnband), dtype=float) dSigma_skn = np.zeros((self.nspins, self.gwnkpt, self.gwnband), dtype=float) Z_skn = np.zeros((self.nspins, self.gwnkpt, self.gwnband), dtype=float) t0 = time() t_w = 0 t_selfenergy = 0 for iq in range(self.q_start, self.q_end): if iq >= self.nqpt: continue t1 = time() # get screened interaction. df, W_wGG = self.screened_interaction_kernel(iq) t2 = time() t_w += t2 - t1 # get self energy S, dS = self.get_self_energy(df, W_wGG) t3 = time() - t2 t_selfenergy += t3 Sigma_skn += S dSigma_skn += dS del df, W_wGG self.timing(iq, t0, self.nq_local, 'iq') self.qcomm.barrier() self.qcomm.sum(Sigma_skn) self.qcomm.sum(dSigma_skn) self.printtxt('W_wGG takes %s ' % (timedelta(seconds=round(t_w)))) self.printtxt('Self energy takes %s ' % (timedelta(seconds=round(t_selfenergy)))) Z_skn = 1. / (1. - dSigma_skn) # exact exchange exx = os.path.isfile(exxfile) world.barrier() if exx: open(exxfile) self.printtxt("reading Exact exchange and E_XC from file") else: t0 = time() self.get_exact_exchange() world.barrier() exxfile = 'EXX.pckl' self.printtxt('EXX takes %s ' % (timedelta(seconds=round(time() - t0)))) data = pickle.load(open(exxfile)) vxc_skn = data['vxc_skn'] # in Hartree exx_skn = data['exx_skn'] # in Hartree f_skn = data['f_skn'] gwkpt_k = data['gwkpt_k'] gwbands_n = data['gwbands_n'] assert (gwkpt_k == self.gwkpt_k ).all(), 'exxfile inconsistent with input parameters' assert (gwbands_n == self.gwbands_n ).all(), 'exxfile inconsistent with input parameters' if self.user_skn is None: e_skn = data['e_skn'] # in Hartree else: e_skn = np.zeros((self.nspins, self.gwnkpt, self.gwnband), dtype=float) for s in range(self.nspins): for i, k in enumerate(self.gwkpt_k): ik = self.kd.bz2ibz_k[k] for j, n in enumerate(self.gwbands_n): if self.user_skn is None: assert e_skn[s][i][j] == self.e_skn[s][ik][ n], 'exxfile inconsistent with eigenvalues' else: e_skn[s][i][j] = self.e_skn[s][ik][n] if not self.static: QP_skn = e_skn + Z_skn * (Sigma_skn + exx_skn - vxc_skn) else: QP_skn = e_skn + Sigma_skn - vxc_skn self.QP_skn = QP_skn # finish self.print_gw_finish(e_skn, f_skn, vxc_skn, exx_skn, Sigma_skn, Z_skn, QP_skn) data = { 'gwkpt_k': self.gwkpt_k, 'gwbands_n': self.gwbands_n, 'f_skn': f_skn, 'e_skn': e_skn, # in Hartree 'vxc_skn': vxc_skn, # in Hartree 'exx_skn': exx_skn, # in Hartree 'Sigma_skn': Sigma_skn, # in Hartree 'Z_skn': Z_skn, # dimensionless 'QP_skn': QP_skn # in Hartree } if rank == 0: pickle.dump(data, open(file, 'w'), -1)
# print "*************** obj, len(obj)", obj.__name__, len(el) assert len(el) == 4 el = obj(calc, energy_range=11.5, txt=txt) # print "*************** obj, len(obj)", obj.__name__, len(el) if hasattr(obj, 'diagonalize'): el.diagonalize() assert len(el) == 18 if hasattr(obj, 'diagonalize'): el.diagonalize(energy_range=8) assert len(el) == 4 lr = LrTDDFT(calc, nspins=2) lr.write('lrtddft3.dat.gz') lr.diagonalize() world.barrier() # This is done to test if writing and reading again yields the same result lr2 = LrTDDFT('lrtddft3.dat.gz') lr2.diagonalize() # Unfortunately not all of the lrtddft code is parallel if rank == 0: Epeak = 19.5# The peak we want to investigate (this is alone) Elist = np.asarray([lrsingle.get_energy() * Hartree for lrsingle in lr]) n = np.argmin(np.abs(Elist - Epeak)) # Index of the peak E = lr[n].get_energy() * Hartree osz = lr[n].get_oscillator_strength() print 'Original object :', E, osz[0]
def main(argv=None): from optparse import OptionParser parser = OptionParser(usage='gwap dataset [options] element') add = parser.add_option add('-f', '--xc-functional', type='string', default='LDA', help='Exchange-Correlation functional (default value LDA)', metavar='<XC>') add('-C', '--configuration', help='e.g. for Li: "[(1, 0, 2, -1.878564), (2, 0, 1, -0.10554),' '(2, 1, 0, 0.0)]"') add('-P', '--projectors', help='Projector functions - use comma-separated - ' + 'nl values, where n can be pricipal quantum number ' + '(integer) or energy (floating point number). ' + 'Example: 2s,0.5s,2p,0.5p,0.0d.') add('-r', '--radius', help='1.2 or 1.2,1.1,1.1') add('-0', '--zero-potential', metavar='nderivs,radius', help='Parameters for zero potential.') add('-c', '--pseudo-core-density-radius', type=float, metavar='radius', help='Radius for pseudizing core density.') add('-z', '--pseudize', metavar='type,nderivs', help='Parameters for pseudizing wave functions.') add('-p', '--plot', action='store_true') add('-l', '--logarithmic-derivatives', metavar='spdfg,e1:e2:de,radius', help='Plot logarithmic derivatives. ' + 'Example: -l spdf,-1:1:0.05,1.3. ' + 'Energy range and/or radius can be left out.') add('-w', '--write', action='store_true') add('-s', '--scalar-relativistic', action='store_true') add('--no-check', action='store_true') add('-t', '--tag', type='string') add('-a', '--alpha', type=float) add('-b', '--create-basis-set', action='store_true') add('--core-hole') add('-e', '--electrons', type=int) add('-o', '--output') opt, symbols = parser.parse_args(argv) for symbol in symbols: kwargs = get_parameters(symbol, opt) gen = _generate(**kwargs) if not opt.no_check: gen.check_all() if opt.create_basis_set or opt.write: basis = None # gen.create_basis_set() if opt.create_basis_set: basis.write_xml() if opt.write: gen.make_paw_setup(opt.tag).write_xml() if opt.logarithmic_derivatives or opt.plot: import matplotlib.pyplot as plt if opt.logarithmic_derivatives: r = 1.1 * gen.rcmax emin = min(min(wave.e_n) for wave in gen.waves_l) - 0.8 emax = max(max(wave.e_n) for wave in gen.waves_l) + 0.8 lvalues, energies, r = parse_ld_str( opt.logarithmic_derivatives, (emin, emax, 0.05), r) ldmax = 0.0 for l in lvalues: ld = gen.aea.logarithmic_derivative(l, energies, r) plt.plot(energies, ld, colors[l], label='spdfg'[l]) ld = gen.logarithmic_derivative(l, energies, r) plt.plot(energies, ld, '--' + colors[l]) # Fixed points: if l < len(gen.waves_l): efix = gen.waves_l[l].e_n ldfix = gen.logarithmic_derivative(l, efix, r) plt.plot(efix, ldfix, 'x' + colors[l]) ldmax = max(ldmax, max(abs(ld) for ld in ldfix)) if l == gen.l0: efix = [0.0] ldfix = gen.logarithmic_derivative(l, efix, r) plt.plot(efix, ldfix, 'x' + colors[l]) ldmax = max(ldmax, max(abs(ld) for ld in ldfix)) if ldmax != 0.0: plt.axis(ymin=-3 * ldmax, ymax=3 * ldmax) plt.xlabel('energy [Ha]') plt.ylabel(r'$d\phi_{\ell\epsilon}(r)/dr/\phi_{\ell\epsilon}' + r'(r)|_{r=r_c}$') plt.legend(loc='best') if opt.plot: gen.plot() if opt.create_basis_set: gen.basis.generatordata = '' # we already printed this BasisPlotter(show=True).plot(gen.basis) try: plt.show() except KeyboardInterrupt: pass world.barrier() return gen
def blacs_mm_to_global(self, H_mm): target = self.MM_descriptor.empty(dtype=complex) self.mm2MM.redistribute(H_mm, target) world.barrier() return target
def blacs_nm_to_global(self, C_nm): target = self.CnM_unique_descriptor.empty(dtype=complex) self.Cnm2nM.redistribute(C_nm, target) world.barrier() return target
def tddft_init(self): if not self.tddft_initialized: if world.rank == 0: print('Initializing real time LCAO TD-DFT calculation.') print('XXX Warning: Array use not optimal for memory.') print('XXX Taylor propagator probably doesn\'t work') print('XXX ...and no arrays are listed in memory estimate yet.') self.blacs = self.wfs.ksl.using_blacs if self.blacs: self.ksl = ksl = self.wfs.ksl nao = ksl.nao nbands = ksl.bd.nbands mynbands = ksl.bd.mynbands blocksize = ksl.blocksize from gpaw.blacs import Redistributor if world.rank == 0: print('BLACS Parallelization') # Parallel grid descriptors self.MM_descriptor = ksl.blockgrid.new_descriptor(nao, nao, nao, nao) # FOR DEBUG self.mm_block_descriptor = ksl.blockgrid.new_descriptor(nao, nao, blocksize, blocksize) self.Cnm_block_descriptor = ksl.blockgrid.new_descriptor(nbands, nao, blocksize, blocksize) #self.CnM_descriptor = ksl.blockgrid.new_descriptor(nbands, nao, mynbands, nao) self.mM_column_descriptor = ksl.single_column_grid.new_descriptor(nao, nao, ksl.naoblocksize, nao) self.CnM_unique_descriptor = ksl.single_column_grid.new_descriptor(nbands, nao, mynbands, nao) # Redistributors self.mm2MM = Redistributor(ksl.block_comm, self.mm_block_descriptor, self.MM_descriptor) # XXX FOR DEBUG self.MM2mm = Redistributor(ksl.block_comm, self.MM_descriptor, self.mm_block_descriptor) # XXX FOR DEBUG self.Cnm2nM = Redistributor(ksl.block_comm, self.Cnm_block_descriptor, self.CnM_unique_descriptor) self.CnM2nm = Redistributor(ksl.block_comm, self.CnM_unique_descriptor, self.Cnm_block_descriptor) self.mM2mm = Redistributor(ksl.block_comm, self.mM_column_descriptor, self.mm_block_descriptor) for kpt in self.wfs.kpt_u: scalapack_zero(self.mm_block_descriptor, kpt.S_MM,'U') scalapack_zero(self.mm_block_descriptor, kpt.T_MM,'U') # XXX to propagator class if self.propagator == 'taylor' and self.blacs: # cholS_mm = self.mm_block_descriptor.empty(dtype=complex) for kpt in self.wfs.kpt_u: kpt.invS_MM = kpt.S_MM.copy() scalapack_inverse(self.mm_block_descriptor, kpt.invS_MM, 'L') if self.propagator_debug: if world.rank == 0: print('XXX Doing serial inversion of overlap matrix.') self.timer.start('Invert overlap (serial)') invS2_MM = self.MM_descriptor.empty(dtype=complex) for kpt in self.wfs.kpt_u: #kpt.S_MM[:] = 128.0*(2**world.rank) self.mm2MM.redistribute(self.wfs.S_qMM[kpt.q], invS2_MM) world.barrier() if world.rank == 0: tri2full(invS2_MM,'L') invS2_MM[:] = inv(invS2_MM.copy()) self.invS2_MM = invS2_MM kpt.invS2_MM = ksl.mmdescriptor.empty(dtype=complex) self.MM2mm.redistribute(invS2_MM, kpt.invS2_MM) verify(kpt.invS_MM, kpt.invS2_MM, 'overlap par. vs. serial', 'L') self.timer.stop('Invert overlap (serial)') if world.rank == 0: print('XXX Overlap inverted.') if self.propagator == 'taylor' and not self.blacs: tmp = inv(self.wfs.kpt_u[0].S_MM) self.wfs.kpt_u[0].invS = tmp # Reset the density mixer self.density.mixer = DummyMixer() self.tddft_initialized = True for k, kpt in enumerate(self.wfs.kpt_u): kpt.C2_nM = kpt.C_nM.copy()
def get_QP_spectrum(self, exxfile='EXX.pckl', file='GW.pckl'): try: self.ini except: self.initialize() self.print_gw_init() self.printtxt("calculating Self energy") Sigma_skn = np.zeros((self.nspins, self.gwnkpt, self.gwnband), dtype=float) dSigma_skn = np.zeros((self.nspins, self.gwnkpt, self.gwnband), dtype=float) Z_skn = np.zeros((self.nspins, self.gwnkpt, self.gwnband), dtype=float) t0 = time() t_w = 0 t_selfenergy = 0 for iq in range(self.q_start, self.q_end): if iq >= self.nqpt: continue t1 = time() # get screened interaction. df, W_wGG = self.screened_interaction_kernel(iq) t2 = time() t_w += t2 - t1 # get self energy S, dS = self.get_self_energy(df, W_wGG) t3 = time() - t2 t_selfenergy += t3 Sigma_skn += S dSigma_skn += dS del df, W_wGG self.timing(iq, t0, self.nq_local, 'iq') self.qcomm.barrier() self.qcomm.sum(Sigma_skn) self.qcomm.sum(dSigma_skn) self.printtxt('W_wGG takes %s ' %(timedelta(seconds=round(t_w)))) self.printtxt('Self energy takes %s ' %(timedelta(seconds=round(t_selfenergy)))) Z_skn = 1. / (1. - dSigma_skn) # exact exchange exx = os.path.isfile(exxfile) world.barrier() if exx: open(exxfile) self.printtxt("reading Exact exchange and E_XC from file") else: t0 = time() self.get_exact_exchange() world.barrier() exxfile='EXX.pckl' self.printtxt('EXX takes %s ' %(timedelta(seconds=round(time()-t0)))) data = pickle.load(open(exxfile)) vxc_skn = data['vxc_skn'] # in Hartree exx_skn = data['exx_skn'] # in Hartree f_skn = data['f_skn'] gwkpt_k = data['gwkpt_k'] gwbands_n = data['gwbands_n'] assert (gwkpt_k == self.gwkpt_k).all(), 'exxfile inconsistent with input parameters' assert (gwbands_n == self.gwbands_n).all(), 'exxfile inconsistent with input parameters' if self.user_skn is None: e_skn = data['e_skn'] # in Hartree else: e_skn = np.zeros((self.nspins, self.gwnkpt, self.gwnband), dtype=float) for s in range(self.nspins): for i, k in enumerate(self.gwkpt_k): ik = self.kd.bz2ibz_k[k] for j, n in enumerate(self.gwbands_n): if self.user_skn is None: assert e_skn[s][i][j] == self.e_skn[s][ik][n], 'exxfile inconsistent with eigenvalues' else: e_skn[s][i][j] = self.e_skn[s][ik][n] if not self.static: QP_skn = e_skn + Z_skn * (Sigma_skn + exx_skn - vxc_skn) else: QP_skn = e_skn + Sigma_skn - vxc_skn self.QP_skn = QP_skn # finish self.print_gw_finish(e_skn, f_skn, vxc_skn, exx_skn, Sigma_skn, Z_skn, QP_skn) data = { 'gwkpt_k': self.gwkpt_k, 'gwbands_n': self.gwbands_n, 'f_skn': f_skn, 'e_skn': e_skn, # in Hartree 'vxc_skn': vxc_skn, # in Hartree 'exx_skn': exx_skn, # in Hartree 'Sigma_skn': Sigma_skn, # in Hartree 'Z_skn': Z_skn, # dimensionless 'QP_skn': QP_skn # in Hartree } if rank == 0: pickle.dump(data, open(file, 'w'), -1)
# second atom first atom print 'PBE energy minimum:' print 'hydrogen molecule energy: %7.3f eV' % e2 print 'bondlength : %7.3f Ang' % d0 molecule = GPAW('H2fa.gpw', txt='H2.txt').get_atoms() relax = BFGS(molecule) relax.run(fmax=0.05) e2q = molecule.get_potential_energy() niter2q = calc.get_number_of_iterations() positions = molecule.get_positions() d0q = positions[1, 0] - positions[0, 0] assert abs(e2 - e2q) < 2e-6 assert abs(d0q - d0) < 4e-4 f0 = molecule.get_forces() del relax, molecule from gpaw.mpi import world world.barrier() # syncronize before reading text output file f = read('H2.txt').get_forces() assert abs(f - f0).max() < 5e-6 # 5 digits in txt file energy_tolerance = 0.00005 niter_tolerance = 0 equal(e1, -6.287873, energy_tolerance) equal(e2, -6.290744, energy_tolerance) equal(e2q, -6.290744, energy_tolerance)
df = DielectricFunction(calc='Al', frequencies=w, eta=0.2, ecut=50, hilbert=False) df.get_eels_spectrum(xc='ALDA', filename='EELS_Al_ALDA', q_c=q) #df.check_sum_rule() #df.write('Al.pckl') t3 = time.time() print('For ground state calc, it took', (t2 - t1) / 60, 'minutes') print('For excited state calc, it took', (t3 - t2) / 60, 'minutes') world.barrier() d = np.loadtxt('EELS_Al_ALDA', delimiter=',') # New results are compared with test values wpeak1, Ipeak1 = findpeak(d[:, 0], d[:, 1]) wpeak2, Ipeak2 = findpeak(d[:, 0], d[:, 2]) test_wpeak1 = 15.4929666813 # eV test_Ipeak1 = 29.644489594 test_wpeak2 = 15.5196459206 # eV test_Ipeak2 = 26.5680624522 if abs(test_wpeak1 - wpeak1) > 0.02 or abs(test_wpeak2 - wpeak2) > 0.02: print((test_wpeak1 - wpeak1, test_wpeak2 - wpeak2)) raise ValueError('Plasmon peak not correct ! ') if abs(test_Ipeak1 - Ipeak1) > 1 or abs(test_Ipeak2 - Ipeak2) > 1:
def get_excitation_wavefunction(self, lamda=None, filename=None, re_c=None, rh_c=None): if filename is not None: self.load(filename) self.initialize() gd = self.gd w_S = self.w_S v_SS = self.v_SS A_S = v_SS[:, lamda] kq_k = self.kq_k kd = self.kd if re_c is not None: psith_R = gd.zeros(dtype=complex) elif rh_c is not None: psite_R = gd.zeros(dtype=complex) else: self.printtxt('No wavefunction output !') return for iS in range(self.nS_start, self.nS_end): print 'hole wavefunction', iS k, n, m = self.Sindex_S3[iS] ibzkpt1 = kd.kibz_k[k] ibzkpt2 = kd.kibz_k[kq_k[k]] psitold_g = self.get_wavefunction(ibzkpt1, n) psit1_g = kd.transform_wave_function(psitold_g, k) psitold_g = self.get_wavefunction(ibzkpt2, m) psit2_g = kd.transform_wave_function(psitold_g, kq_k[k]) if re_c is not None: # given electron position, plot hole wavefunction psith_R += A_S[iS] * psit1_g[re_c].conj() * psit2_g elif rh_c is not None: # given hole position, plot electron wavefunction psite_R += A_S[iS] * psit1_g.conj() * psit2_g[rh_c] else: pass if re_c is not None: self.Scomm.sum(psith_R) if rank == 0: write('psit_h.cube', self.calc.atoms, format='cube', data=psith_R) elif rh_c is not None: self.Scomm.sum(psite_R) if rank == 0: write('psit_e.cube', self.calc.atoms, format='cube', data=psite_R) else: pass world.barrier() return
def calculate(self): calc = self.calc f_skn = self.f_skn e_skn = self.e_skn kq_k = self.kq_k focc_S = self.focc_S e_S = self.e_S op_scc = calc.wfs.symmetry.op_scc # Get phi_qaGp if self.mode == 'RPA': self.phi_aGp = self.get_phi_aGp() else: try: self.reader = Reader('phi_qaGp') tmp = self.load_phi_aGp(self.reader, 0)[0] assert len(tmp) == self.npw self.printtxt('Finished reading phi_aGp') except: self.printtxt('Calculating phi_qaGp') self.get_phi_qaGp() world.barrier() self.reader = Reader('phi_qaGp') self.printtxt('Memory used %f M' % (maxrss() / 1024.**2)) self.printtxt('') if self.optical_limit: iq = np.where(np.sum(abs(self.ibzq_qc), axis=1) < 1e-5)[0][0] else: iq = np.where(np.sum(abs(self.ibzq_qc - self.q_c), axis=1) < 1e-5)[0][0] kc_G = np.array([self.V_qGG[iq, iG, iG] for iG in range(self.npw)]) if self.optical_limit: kc_G[0] = 0. # Get screened Coulomb kernel if self.mode == 'BSE': try: # Read data = pickle.load(open(self.kernel_file+'.pckl')) W_qGG = data['W_qGG'] assert np.shape(W_qGG) == np.shape(self.V_qGG) self.printtxt('Finished reading screening interaction kernel') except: # Calculate from scratch self.printtxt('Calculating screening interaction kernel.') W_qGG = self.full_static_screened_interaction() self.printtxt('') else: W_qGG = self.V_qGG t0 = time() self.printtxt('Calculating %s matrix elements' % self.mode) # Calculate full kernel K_SS = np.zeros((self.nS_local, self.nS), dtype=complex) self.rhoG0_S = np.zeros(self.nS, dtype=complex) #noGmap = 0 for iS in range(self.nS_start, self.nS_end): k1, n1, m1 = self.Sindex_S3[iS] rho1_G = self.density_matrix(n1,m1,k1) self.rhoG0_S[iS] = rho1_G[0] for jS in range(self.nS): k2, n2, m2 = self.Sindex_S3[jS] rho2_G = self.density_matrix(n2,m2,k2) K_SS[iS-self.nS_start, jS] = np.sum(rho1_G.conj() * rho2_G * kc_G) if not self.mode == 'RPA': rho3_G = self.density_matrix(n1,n2,k1,k2) rho4_G = self.density_matrix(m1,m2,self.kq_k[k1], self.kq_k[k2]) q_c = self.kd.bzk_kc[k2] - self.kd.bzk_kc[k1] q_c[np.where(q_c > 0.501)] -= 1. q_c[np.where(q_c < -0.499)] += 1. iq = self.kd.where_is_q(q_c, self.bzq_qc) if not self.qsymm: W_GG = W_qGG[iq] else: ibzq = self.ibzq_q[iq] W_GG_tmp = W_qGG[ibzq] iop = self.iop_q[iq] timerev = self.timerev_q[iq] diff_c = self.diff_qc[iq] invop = np.linalg.inv(op_scc[iop]) Gindex = np.zeros(self.npw, dtype=int) for iG in range(self.npw): G_c = self.Gvec_Gc[iG] if timerev: RotG_c = -np.int8(np.dot(invop, G_c+diff_c).round()) else: RotG_c = np.int8(np.dot(invop, G_c+diff_c).round()) tmp_G = np.abs(self.Gvec_Gc - RotG_c).sum(axis=1) try: Gindex[iG] = np.where(tmp_G < 1e-5)[0][0] except: #noGmap += 1 Gindex[iG] = -1 W_GG = np.zeros_like(W_GG_tmp) for iG in range(self.npw): for jG in range(self.npw): if Gindex[iG] == -1 or Gindex[jG] == -1: W_GG[iG, jG] = 0 else: W_GG[iG, jG] = W_GG_tmp[Gindex[iG], Gindex[jG]] if self.mode == 'BSE': tmp_GG = np.outer(rho3_G.conj(), rho4_G) * W_GG K_SS[iS-self.nS_start, jS] -= 0.5 * np.sum(tmp_GG) else: tmp_G = rho3_G.conj() * rho4_G * np.diag(W_GG) K_SS[iS-self.nS_start, jS] -= 0.5 * np.sum(tmp_G) self.timing(iS, t0, self.nS_local, 'pair orbital') K_SS /= self.vol world.sum(self.rhoG0_S) #self.printtxt('Number of G indices outside the Gvec_Gc: %d' % noGmap) # Get and solve Hamiltonian H_sS = np.zeros_like(K_SS) for iS in range(self.nS_start, self.nS_end): H_sS[iS-self.nS_start,iS] = e_S[iS] for jS in range(self.nS): H_sS[iS-self.nS_start,jS] += focc_S[iS] * K_SS[iS-self.nS_start,jS] # Force matrix to be Hermitian if not self.coupling: if world.size > 1: H_Ss = self.redistribute_H(H_sS) else: H_Ss = H_sS H_sS = (np.real(H_sS) + np.real(H_Ss.T)) / 2. + 1j * (np.imag(H_sS) - np.imag(H_Ss.T)) /2. # Save H_sS matrix self.par_save('H_SS','H_SS', H_sS) return H_sS
def initialize(self, tp): kw = tp.analysis_parameters if self.restart: self.initialize_selfenergy_and_green_function(tp) else: self.selfenergies = tp.selfenergies p = self.set_default_analysis_parameters() for key in kw: if key in ['energies', 'lead_pairs', 'dos_project_atoms', 'project_equal_atoms', 'project_molecular_levels', 'isolate_atoms', 'dos_project_orbital', 'trans_project_orbital', 'eig_trans_channel_energies', 'eig_trans_channel_num', 'dos_realspace_energies']: p[key] = kw[key] for key in p: vars(self)[key] = p[key] ef = tp.lead_fermi[0] path = tp.contour.get_plot_path() self.energies = path.energies self.my_energies = path.my_energies self.weights = path.weights self.my_weights = path.my_weights self.nids = path.nids self.my_nids = path.my_nids for variable in [self.eig_trans_channel_energies, self.dos_realspace_energies]: if variable is not None: variable = np.array(variable) + ef ecomm = tp.contour.comm if self.eig_trans_channel_energies is not None: self.my_eig_trans_channel_energies = np.array_split( self.eig_trans_channel_energies, ecomm.size)[ecomm.rank] self.my_eig_trans_channel_nids = np.array_split( np.arange(len(self.eig_trans_channel_energies)), ecomm.size)[ecomm.rank] if self.dos_realspace_energies is not None: self.my_dos_realspace_energies = np.array_split( self.dos_realspace_energies, ecomm.size)[ecomm.rank] self.my_dos_realspace_nids = np.array_split( np.arange(len(self.dos_realspace_energies)), ecomm.size)[ecomm.rank] setups = tp.inner_setups self.project_atoms_in_device = self.project_equal_atoms[0] self.project_atoms_in_molecule = self.project_equal_atoms[1] self.project_basis_in_device = get_atom_indices( self.project_atoms_in_device, setups) if self.isolate_atoms is not None: self.calculate_isolate_molecular_levels(tp) self.overhead_data_saved = False if world.rank == 0: if not os.access('analysis_data', os.F_OK): os.mkdir('analysis_data') if not os.access('analysis_data/ionic_step_0', os.F_OK): os.mkdir('analysis_data/ionic_step_0') world.barrier() self.data = {}
def borncharges(calc, delta=0.01): params = calc.parameters atoms = calc.atoms cell_cv = atoms.get_cell() / Bohr vol = abs(np.linalg.det(cell_cv)) sym_a = atoms.get_chemical_symbols() Z_a = [] for num in calc.atoms.get_atomic_numbers(): for ida, setup in zip(calc.wfs.setups.id_a, calc.wfs.setups): if abs(ida[0] - num) < 1e-5: break Z_a.append(setup.Nv) Z_a = np.array(Z_a) # List for atomic indices indices = list(range(len(sym_a))) pos_av = atoms.get_positions() avg_v = np.sum(pos_av, axis=0) / len(pos_av) pos_av -= avg_v atoms.set_positions(pos_av) Z_avv = [] norm_c = np.linalg.norm(cell_cv, axis=1) proj_cv = cell_cv / norm_c[:, np.newaxis] B_cv = np.linalg.inv(cell_cv).T * 2 * np.pi area_c = np.zeros((3,), float) area_c[[2, 1, 0]] = [np.linalg.norm(np.cross(B_cv[i], B_cv[j])) for i in range(3) for j in range(3) if i < j] if world.rank == 0: print('Atomnum Atom Direction Displacement') for a in indices: phase_scv = np.zeros((2, 3, 3), float) for v in range(3): for s, sign in enumerate([-1, 1]): if world.rank == 0: print(sym_a[a], a, v, s) # Update atomic positions atoms.positions = pos_av atoms.positions[a, v] = pos_av[a, v] + sign * delta prefix = 'born-{}-{}{}{}'.format(delta, a, 'xyz'[v], ' +-'[sign]) name = prefix + '.gpw' berryname = prefix + '-berryphases.json' if not exists(name) and not exists(berryname): calc = get_wavefunctions(atoms, name, params) try: phase_c = get_polarization_phase(name) except ValueError: calc = get_wavefunctions(atoms, name, params) phase_c = get_polarization_phase(name) phase_scv[s, :, v] = phase_c if exists(berryname): # Calculation done? if world.rank == 0: # Remove gpw file if isfile(name): remove(name) dphase_cv = (phase_scv[1] - phase_scv[0]) dphase_cv -= np.round(dphase_cv / (2 * np.pi)) * 2 * np.pi dP_cv = (area_c[:, np.newaxis] / (2 * np.pi)**3 * dphase_cv) dP_vv = np.dot(proj_cv.T, dP_cv) Z_vv = dP_vv * vol / (2 * delta / Bohr) Z_avv.append(Z_vv) data = {'Z_avv': Z_avv, 'indices_a': indices, 'sym_a': sym_a} filename = 'borncharges-{}.json'.format(delta) with paropen(filename, 'w') as fd: json.dump(jsonio.encode(data), fd) world.barrier() if world.rank == 0: files = glob('born-*.gpw') for f in files: if isfile(f): remove(f)
def main(argv=None): from optparse import OptionParser parser = OptionParser(usage='gwap dataset [options] element') add = parser.add_option add('-f', '--xc-functional', type='string', default='LDA', help='Exchange-Correlation functional (default value LDA)', metavar='<XC>') add('-C', '--configuration', help='e.g. for Li: "[(1, 0, 2, -1.878564), (2, 0, 1, -0.10554),' ' (2, 1, 0, 0.0)]"') add('-P', '--projectors', help='Projector functions - use comma-separated - ' + 'nl values, where n can be principal quantum number ' + '(integer) or energy (floating point number). ' + 'Example: 2s,0.5s,2p,0.5p,0.0d.') add('-r', '--radius', help='1.2 or 1.2,1.1,1.1') add('-0', '--zero-potential', metavar='nderivs,radius', help='Parameters for zero potential.') add('-c', '--pseudo-core-density-radius', type=float, metavar='radius', help='Radius for pseudizing core density.') add('-z', '--pseudize', metavar='type,nderivs', help='Parameters for pseudizing wave functions.') add('-p', '--plot', action='store_true') add('-l', '--logarithmic-derivatives', metavar='spdfg,e1:e2:de,radius', help='Plot logarithmic derivatives. ' + 'Example: -l spdf,-1:1:0.05,1.3. ' + 'Energy range and/or radius can be left out.') add('-w', '--write', action='store_true') add('-s', '--scalar-relativistic', action='store_true') add('-n', '--no-check', action='store_true') add('-t', '--tag', type='string') add('-a', '--alpha', type=float) add('-b', '--create-basis-set', action='store_true') add('--nlcc', action='store_true', help='Use NLCC-style pseudo core density (for vdW-DF functionals).') add('--core-hole') add('-e', '--electrons', type=int) add('-o', '--output') opt, symbols = parser.parse_args(argv) for symbol in symbols: kwargs = get_parameters(symbol, opt) gen = _generate(**kwargs) if not opt.no_check: if not gen.check_all(): raise DatasetGenerationError if opt.create_basis_set or opt.write: basis = gen.create_basis_set() if opt.create_basis_set: basis.write_xml() if opt.write: setup = gen.make_paw_setup(opt.tag) parameters = [] for key, value in kwargs.items(): if value is not None: parameters.append('{0}={1!r}'.format(key, value)) setup.generatordata = ',\n '.join(parameters) setup.write_xml() if opt.logarithmic_derivatives or opt.plot: if opt.plot: import matplotlib.pyplot as plt if opt.logarithmic_derivatives: r = 1.1 * gen.rcmax emin = min(min(wave.e_n) for wave in gen.waves_l) - 0.8 emax = max(max(wave.e_n) for wave in gen.waves_l) + 0.8 lvalues, energies, r = parse_ld_str( opt.logarithmic_derivatives, (emin, emax, 0.05), r) emin = energies[0] de = energies[1] - emin error = 0.0 for l in lvalues: efix = [] # Fixed points: if l < len(gen.waves_l): efix.extend(gen.waves_l[l].e_n) if l == gen.l0: efix.append(0.0) ld1 = gen.aea.logarithmic_derivative(l, energies, r) ld2 = gen.logarithmic_derivative(l, energies, r) for e in efix: i = int((e - emin) / de) if 0 <= i < len(energies): ld1 -= round(ld1[i] - ld2[i]) if opt.plot: ldfix = ld1[i] plt.plot([energies[i]], [ldfix], 'x' + colors[l]) if opt.plot: plt.plot(energies, ld1, colors[l], label='spdfg'[l]) plt.plot(energies, ld2, '--' + colors[l]) error = abs(ld1 - ld2).sum() * de print('Logarithmic derivative error:', l, error) if opt.plot: plt.xlabel('energy [Ha]') plt.ylabel(r'$\arctan(d\log\phi_{\ell\epsilon}(r)/dr)/\pi' r'|_{r=r_c}$') plt.legend(loc='best') if opt.plot: gen.plot() if opt.create_basis_set: gen.basis.generatordata = '' # we already printed this BasisPlotter(show=True).plot(gen.basis) if opt.plot: try: plt.show() except KeyboardInterrupt: pass world.barrier() return gen