def calculate_renormalized_kernel(pd, calc, functional, fd): """Renormalized kernel""" from gpaw.xc.fxc import KernelDens kernel = KernelDens(calc, functional, [pd.kd.bzk_kc[0]], fd, calc.wfs.kd.N_c, None, ecut=pd.ecut * Ha, tag='', timer=Timer()) kernel.calculate_fhxc() r = Reader('fhxc_%s_%s_%s_%s.gpw' % ('', functional, pd.ecut * Ha, 0)) Kxc_sGG = np.array([r.get('fhxc_sGsG')]) v_G = 4 * np.pi / pd.G2_qG[0] Kxc_sGG[0] -= np.diagflat(v_G) if pd.kd.gamma: Kxc_sGG[:, 0, :] = 0.0 Kxc_sGG[:, :, 0] = 0.0 return Kxc_sGG
def get_xc_kernel(pd, chi0, functional='ALDA', chi0_wGG=None): """Factory function that calls the relevant functions below""" calc = chi0.calc fd = chi0.fd nspins = len(calc.density.nt_sG) assert nspins == 1 if functional[0] == 'A': # Standard adiabatic kernel print('Calculating %s kernel' % functional, file=fd) Kxc_sGG = calculate_Kxc(pd, calc, functional=functional) elif functional[0] == 'r': # Renormalized kernel print('Calculating %s kernel' % functional, file=fd) from gpaw.xc.fxc import KernelDens kernel = KernelDens( calc, functional, [pd.kd.bzk_kc[0]], fd, calc.wfs.kd.N_c, None, ecut=pd.ecut * Ha, tag='', timer=Timer(), ) kernel.calculate_fhxc() r = Reader('fhxc_%s_%s_%s_%s.gpw' % ('', functional, pd.ecut * Ha, 0)) Kxc_sGG = np.array([r.get('fhxc_sGsG')]) v_G = 4 * np.pi / pd.G2_qG[0] Kxc_sGG[0] -= np.diagflat(v_G) if pd.kd.gamma: Kxc_sGG[:, 0, :] = 0.0 Kxc_sGG[:, :, 0] = 0.0 elif functional[:2] == 'LR': print('Calculating LR kernel with alpha = %s' % functional[2:], file=fd) Kxc_sGG = calculate_lr_kernel(pd, calc, alpha=float(functional[2:])) elif functional == 'DM': print('Calculating DM kernel', file=fd) Kxc_sGG = calculate_dm_kernel(pd, calc) elif functional == 'Bootstrap': print('Calculating Bootstrap kernel', file=fd) if chi0.world.rank == 0: chi0_GG = chi0_wGG[0] chi0.world.broadcast(chi0_GG, 0) else: nG = pd.ngmax chi0_GG = np.zeros((nG, nG), complex) chi0.world.broadcast(chi0_GG, 0) Kxc_sGG = calculate_bootstrap_kernel(pd, chi0_GG, fd) else: raise ValueError('%s kernel not implemented' % functional) return Kxc_sGG
def startElement(self, tag, attrs): if tag == 'partition': name = attrs['name'] assert name not in self.partitions.keys() self.dtypes[name] = attrs['type'] self.shapes[name] = [] self.name = name self.partitions[name] = tuple() else: if tag == 'dimension' and self.name in self.partitions.keys(): if attrs['name'] == self._iterkey: self.partitions[self.name] += (self._partkey,) else: self.partitions[self.name] += (attrs['name'],) Reader.startElement(self, tag, attrs)
def get_data_type(self, name): if name not in self.dtypes.keys(): try: name, partname = name.rsplit('/', 1) except ValueError: raise KeyError(name) assert name in self.partitions.keys() return Reader.get_data_type(self, name)
def get_data_type(self, name): if name not in self.dtypes.keys(): try: name, partname = name.rsplit('/',1) except ValueError: raise KeyError(name) assert name in self.partitions.keys() return Reader.get_data_type(self, name)
def read(self, filename, mode='', ws='all', idiotproof=True): if idiotproof and not filename.endswith('.ind'): raise IOError('Filename must end with `.ind`.') reads = self._parse_readwritemode(mode) # Open reader (handles masters) tar = Reader(filename) # Actual read self.nw = tar.dimension('nw') if ws == 'all': ws = range(self.nw) self.nw = len(ws) self._read(tar, reads, ws) # Close tar.close() self.world.barrier()
def get_file_object(self, name, indices): if name in self.partitions.keys(): # The first index is the partition iterable if len(indices) == 0: return self.get_partition_object(name) i, indices = indices[0], indices[1:] partshape = [self.dims[dim] for dim in self.partitions[name]] name += self._iterpattern % i self.shapes[name] = partshape[1:] #HACK return Reader.get_file_object(self, name, indices)
def get_file_object(self, name, indices): if name in self.partitions.keys(): # The first index is the partition iterable if len(indices) == 0: return self.get_partition_object(name) i, indices = indices[0], indices[1:] partshape = [self.dims[dim] for dim in self.partitions[name]] name += self._iterpattern % i self.shapes[name] = partshape[1:] # HACK return Reader.get_file_object(self, name, indices)
def dscf_load_band(filename, paw, molecule=None): """Load and distribute all information for a band from a tar file.""" if not paw.wfs: paw.initialize() world, bd, gd, kd = paw.wfs.world, paw.wfs.bd, paw.wfs.gd, \ KPointDescriptor(paw.wfs.nspins, paw.wfs.nibzkpts, paw.wfs.kpt_comm, \ paw.wfs.gamma, paw.wfs.dtype) if bd.comm.size != 1: raise NotImplementedError('Undefined action for band parallelization.') r = Reader(filename) assert (r.dimension('nspins') == kd.nspins and \ r.dimension('nibzkpts') == kd.nibzkpts), 'Incompatible spin/kpoints.' # Read wave function for every spin/kpoint owned by this rank psit_uG = gd.empty(kd.mynks, kd.dtype) for myu, psit_G in enumerate(psit_uG): u = kd.global_index(myu) s, k = kd.what_is(u) if gd.comm.rank == 0: big_psit_G = np.array(r.get('PseudoWaveFunction', s, k), kd.dtype) else: big_psit_G = None gd.distribute(big_psit_G, psit_G) # Find domain ranks for each atom atoms = paw.get_atoms() spos_ac = atoms.get_scaled_positions() % 1.0 rank_a = gd.get_ranks_from_positions(spos_ac) #my_atom_indices = np.argwhere(rank_a == gd.comm.rank).ravel() #assert np.all(my_atom_indices == paw.wfs.pt.my_atom_indices) assert r.dimension('nproj') == sum([setup.ni for setup in paw.wfs.setups]) if molecule is None: molecule = range(len(atoms)) # Read projections for every spin/kpoint and atom owned by this rank P_uai = [{}] * kd.mynks #[paw.wfs.pt.dict() for myu in range(kd.mynks)] for myu, P_ai in enumerate(P_uai): u = kd.global_index(myu) s, k = kd.what_is(u) P_i = r.get('Projection', s, k) i1 = 0 for a in molecule: setup = paw.wfs.setups[a] i2 = i1 + setup.ni if gd.comm.rank == rank_a[a]: P_ai[a] = np.array(P_i[i1:i2], kd.dtype) i1 = i2 return psit_uG, P_uai
def read_data(filename, keys=None, ws='all'): """ Read data arrays for post processing. Not parallel safe. No GridDescriptor, only numpy arrays. Parameters ---------- filename: string File to be read. keys: list of strings Keys to be read. ws: list of ints Indices of frequencies to be read. """ key_to_tarname = { 'n0t_sG': 'n0t_sG', 'Fnt_wsG': 'Fnt_wsG', 'Frho_wg': 'Frho_wg', 'Fphi_wg': 'Fphi_wg', 'Fef_wvg': 'Fef_wvg', 'Ffe_wg': 'Ffe_wg', 'eps0_G': 'eps0_G' } print('Reading %s' % (filename)) if keys is None: keys = key_to_tarname.keys() # all keys tar = Reader(filename) omega_w = tar.get('omega_w') if ws == 'all': ws = range(len(omega_w)) else: omega_w = omega_w[ws] freq_w = omega_w * aufrequency_to_eV try: nspins = tar.dimension('nspins') except KeyError: nspins = None na = tar['na'] try: atomnum_a = tar.get('atomnum_a') atompos_av = tar.get('atompos_a') atomcell_cv = tar.get('atomcell_cv') Fbgef_v = tar.get('Fbgef_v') atom_a = [] for a in range(na): atom_a.append({'atom': atomnum_a[a], 'pos': atompos_av[a]}) except KeyError: atom_a = None atomcell_cv = None Fbgef_v = None print('no atoms') data = dict() data['freq_w'] = freq_w data['nspins'] = nspins data['na'] = na data['atom_a'] = atom_a data['cell_cv'] = atomcell_cv data['Fbgef_v'] = Fbgef_v try: data['corner1_v'] = tar.get('corner1_v') data['corner2_v'] = tar.get('corner2_v') except: print('no corners') try: FD_awsp = {} D0_asp = {} for a in range(na): FD_awsp[a] = tar.get('FD_%dwsp' % a) D0_asp[a] = tar.get('D0_%dsp' % a) data['FD_awsp'] = FD_awsp data['D0_asp'] = D0_asp except KeyError: print('no FD_awsp') for key in keys: try: if '_w' in key: tmp = zero_pad(tar.get(key_to_tarname[key], ws[0])) data[key] = np.empty((len(ws), ) + tmp.shape, tmp.dtype) data[key][0] = tmp for w, wread in enumerate(ws[1:], 1): data[key][w] = zero_pad(tar.get(key_to_tarname[key], wread)) else: data[key] = zero_pad(tar.get(key_to_tarname[key])) except KeyError: print('no %s' % key) pass tar.close() return data
def __init__(self, name): self.partitions = {} Reader.__init__(self, name) self.dims[self._partkey] = 1
def read(self, filename, idiotproof=True): if idiotproof and not filename.endswith('.ftd'): raise IOError('Filename must end with `.ftd`.') tar = Reader(filename) # Test data type dtype = {'Float':float, 'Complex':complex}[tar['DataType']] if dtype != self.dtype: raise IOError('Data is an incompatible type.') # Test time time = tar['Time'] if idiotproof and abs(time-self.time) >= 1e-9: raise IOError('Timestamp is incompatible with calculator.') # Test timestep (non-critical) timestep = tar['TimeStep'] if abs(timestep - self.timestep) > 1e-12: print 'Warning: Time-step has been altered. (%lf -> %lf)' \ % (self.timestep, timestep) self.timestep = timestep # Test dimensions nw = tar.dimension('nw') nspins = tar.dimension('nspins') ng = (tar.dimension('ngptsx'), tar.dimension('ngptsy'), \ tar.dimension('ngptsz'),) if (nw != self.nw or nspins != self.nspins or (ng != self.gd.get_size_of_global_array()).any()): raise IOError('Data has incompatible shapes.') # Test width (non-critical) sigma = tar['Width'] if ((sigma is None)!=(self.sigma is None) or # float <-> None (sigma is not None and self.sigma is not None and \ abs(sigma - self.sigma) > 1e-12)): # float -> float print 'Warning: Width has been altered. (%s -> %s)' \ % (self.sigma, sigma) self.sigma = sigma # Read frequencies self.omega_w[:] = tar.get('Frequency') # Read cumulative phase factors self.gamma_w[:] = tar.get('PhaseFactor') # Read average densities on master and distribute for s in range(self.nspins): all_Ant_G = tar.get('Average', s) self.gd.distribute(all_Ant_G, self.Ant_sG[s]) # Read fourier transforms on master and distribute for w in range(self.nw): for s in range(self.nspins): all_Fnt_G = tar.get('FourierTransform', w, s) self.gd.distribute(all_Fnt_G, self.Fnt_wsG[w,s]) # Close for good measure tar.close()
def calculate(self): calc = self.calc focc_S = self.focc_S e_S = self.e_S op_scc = calc.wfs.kd.symmetry.op_scc # Get phi_qaGp if self.mode == 'RPA': self.phi_aGp = self.get_phi_aGp() else: fd = opencew('phi_qaGp') if fd is None: 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') else: 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
print ' %s FTDFILE GPWFILE' % scriptname print '' print 'Arguments:' print ' FTDFILE Fourier transformed density tar-file.' print ' GPWFILE GPAW calculation tar-file (optional).' print '' try: assert len(sys.argv) == 3, 'Incorrect number of arguments.' ftd_filename = sys.argv[1] assert ftd_filename.endswith('.ftd'), 'Invalid FTD tarfile.' assert os.path.isfile(ftd_filename), 'FTD tarfile not found.' prefix = ftd_filename.rsplit('.ftd', 1)[0] tar = Reader(ftd_filename) try: timestep = tar['TimeStep'] sigma = tar['Width'] except KeyError: timestep = 1 sigma = None omega_w = tar.get('Frequency') gamma_w = tar.get('PhaseFactor') Fnt_wsG = tar.get('FourierTransform') Ant_sG = tar.get('Average') atoms = None del tar gpw_filename = sys.argv[2] assert gpw_filename.endswith('.gpw'), 'Invalid GPW tarfile.'
def wrap_old_gpw_reader(filename): warnings.warn('You are reading an old-style gpw-file. Please check ' 'the results carefully!') r = Reader(filename) data = { 'version': -1, 'gpaw_version': '1.0', 'ha': Ha, 'bohr': Bohr, 'scf.': { 'converged': True }, 'atoms.': {}, 'wave_functions.': {} } class DictBackend: def write(self, **kwargs): data['atoms.'].update(kwargs) write_atoms(DictBackend(), read_atoms(r)) e_total_extrapolated = r.get('PotentialEnergy').item() * Ha magmom_a = r.get('MagneticMoments') data['results.'] = { 'energy': e_total_extrapolated, 'magmoms': magmom_a, 'magmom': magmom_a.sum() } if r.has_array('CartesianForces'): data['results.']['forces'] = r.get('CartesianForces') * Ha / Bohr p = data['parameters.'] = {} p['xc'] = r['XCFunctional'] p['nbands'] = r.dimension('nbands') p['spinpol'] = (r.dimension('nspins') == 2) bzk_kc = r.get('BZKPoints', broadcast=True) if r.has_array('NBZKPoints'): p['kpts'] = r.get('NBZKPoints', broadcast=True) if r.has_array('MonkhorstPackOffset'): offset_c = r.get('MonkhorstPackOffset', broadcast=True) if offset_c.any(): p['kpts'] = monkhorst_pack(p['kpts']) + offset_c else: p['kpts'] = bzk_kc if r['version'] < 4: usesymm = r['UseSymmetry'] if usesymm is None: p['symmetry'] = {'time_reversal': False, 'point_group': False} elif usesymm: p['symmetry'] = {'time_reversal': True, 'point_group': True} else: p['symmetry'] = {'time_reversal': True, 'point_group': False} else: p['symmetry'] = { 'point_group': r['SymmetryOnSwitch'], 'symmorphic': r['SymmetrySymmorphicSwitch'], 'time_reversal': r['SymmetryTimeReversalSwitch'], 'tolerance': r['SymmetryToleranceCriterion'] } p['basis'] = r['BasisSet'] try: h = r['GridSpacing'] except KeyError: # CMR can't handle None! h = None if h is not None: p['h'] = Bohr * h if r.has_array('GridPoints'): p['gpts'] = r.get('GridPoints') p['lmax'] = r['MaximumAngularMomentum'] p['setups'] = r['SetupTypes'] p['fixdensity'] = r['FixDensity'] nbtc = r['NumberOfBandsToConverge'] if not isinstance(nbtc, (int, str)): # The string 'all' was eval'ed to the all() function! nbtc = 'all' p['convergence'] = { 'density': r['DensityConvergenceCriterion'], 'energy': r['EnergyConvergenceCriterion'] * Ha, 'eigenstates': r['EigenstatesConvergenceCriterion'], 'bands': nbtc } mixer = r['MixClass'] weight = r['MixWeight'] for key in ['basis', 'setups']: dct = p[key] if isinstance(dct, dict) and None in dct: dct['default'] = dct.pop(None) 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: p['mixer'] = None else: p['mixer'] = Mixer(r['MixBeta'], r['MixOld'], weight) p['stencils'] = (r['KohnShamStencil'], r['InterpolationStencil']) vt_sG = r.get('PseudoPotential') * Ha ps = r['PoissonStencil'] if isinstance(ps, int) or ps == 'M': poisson = {'name': 'fd'} poisson['nn'] = ps if data['atoms.']['pbc'] == [1, 1, 0]: v1, v2 = vt_sG[0, :, :, [0, -1]].mean(axis=(1, 2)) if abs(v1 - v2) > 0.01: warnings.warn('I am guessing that this calculation was done ' 'with a dipole-layer correction?') poisson['dipolelayer'] = 'xy' p['poissonsolver'] = poisson p['charge'] = r['Charge'] fixmom = r['FixMagneticMoment'] p['occupations'] = FermiDirac(r['FermiWidth'] * Ha, fixmagmom=fixmom) p['mode'] = r['Mode'] if p['mode'] == 'pw': p['mode'] = PW(ecut=r['PlaneWaveCutoff'] * Ha) if len(bzk_kc) == 1 and not bzk_kc[0].any(): # Gamma point only: if r['DataType'] == 'Complex': p['dtype'] = complex data['occupations.'] = { 'fermilevel': r['FermiLevel'] * Ha, 'split': r.parameters.get('FermiSplit', 0) * Ha, 'h**o': np.nan, 'lumo': np.nan } data['density.'] = { 'density': r.get('PseudoElectronDensity') * Bohr**-3, 'atomic_density_matrices': r.get('AtomicDensityMatrices') } data['hamiltonian.'] = { 'e_coulomb': r['Epot'] * Ha, 'e_entropy': -r['S'] * Ha, 'e_external': r['Eext'] * Ha, 'e_kinetic': r['Ekin'] * Ha, 'e_total_extrapolated': e_total_extrapolated, 'e_xc': r['Exc'] * Ha, 'e_zero': r['Ebar'] * Ha, 'potential': vt_sG, 'atomic_hamiltonian_matrices': r.get('NonLocalPartOfHamiltonian') * Ha } data['hamiltonian.']['e_total_free'] = (sum( data['hamiltonian.'][e] for e in [ 'e_coulomb', 'e_entropy', 'e_external', 'e_kinetic', 'e_xc', 'e_zero' ])) if r.has_array('GLLBPseudoResponsePotential'): data['hamiltonian.']['xc.'] = { 'gllb_pseudo_response_potential': r.get('GLLBPseudoResponsePotential') * Ha, 'gllb_dxc_pseudo_response_potential': r.get('GLLBDxcPseudoResponsePotential') * Ha / Bohr, 'gllb_atomic_density_matrices': r.get('GLLBAtomicDensityMatrices'), 'gllb_atomic_response_matrices': r.get('GLLBAtomicResponseMatrices'), 'gllb_dxc_atomic_density_matrices': r.get('GLLBDxcAtomicDensityMatrices'), 'gllb_dxc_atomic_response_matrices': r.get('GLLBDxcAtomicResponseMatrices') } special = [('eigenvalues', 'Eigenvalues'), ('occupations', 'OccupationNumbers'), ('projections', 'Projections')] if r['Mode'] == 'pw': special.append(('coefficients', 'PseudoWaveFunctions')) try: data['wave_functions.']['indices'] = r.get('PlaneWaveIndices') except KeyError: pass elif r['Mode'] == 'fd': special.append(('values', 'PseudoWaveFunctions')) else: special.append(('coefficients', 'WaveFunctionCoefficients')) for name, old in special: try: fd, shape, size, dtype = r.get_file_object(old, ()) except KeyError: continue offset = fd data['wave_functions.'][name + '.'] = { 'ndarray': (shape, dtype.name, offset) } new = ulm.Reader(devnull, data=data, little_endian=r.byteswap ^ np.little_endian) for ref in new._data['wave_functions']._data.values(): try: ref.fd = ref.offset except AttributeError: continue ref.offset = 0 return new
print(' %s FTDFILE GPWFILE' % scriptname) print('') print('Arguments:') print(' FTDFILE Fourier transformed density tar-file.') print(' GPWFILE GPAW calculation tar-file (optional).') print('') try: assert len(sys.argv) == 3, 'Incorrect number of arguments.' ftd_filename = sys.argv[1] assert ftd_filename.endswith('.ftd'), 'Invalid FTD tarfile.' assert os.path.isfile(ftd_filename), 'FTD tarfile not found.' prefix = ftd_filename.rsplit('.ftd', 1)[0] tar = Reader(ftd_filename) try: timestep = tar['TimeStep'] sigma = tar['Width'] except KeyError: timestep = 1 sigma = None omega_w = tar.get('Frequency') gamma_w = tar.get('PhaseFactor') Fnt_wsG = tar.get('FourierTransform') Ant_sG = tar.get('Average') atoms = None del tar gpw_filename = sys.argv[2] assert gpw_filename.endswith('.gpw'), 'Invalid GPW tarfile.'
def read(self, filename, idiotproof=True): if idiotproof and not filename.endswith('.ftd'): raise IOError('Filename must end with `.ftd`.') tar = Reader(filename) # Test data type dtype = {'Float': float, 'Complex': complex}[tar['DataType']] if dtype != self.dtype: raise IOError('Data is an incompatible type.') # Test time time = tar['Time'] if idiotproof and abs(time - self.time) >= 1e-9: raise IOError('Timestamp is incompatible with calculator.') # Test timestep (non-critical) timestep = tar['TimeStep'] if abs(timestep - self.timestep) > 1e-12: print('Warning: Time-step has been altered. (%lf -> %lf)' \ % (self.timestep, timestep)) self.timestep = timestep # Test dimensions nw = tar.dimension('nw') nspins = tar.dimension('nspins') ng = (tar.dimension('ngptsx'), tar.dimension('ngptsy'), \ tar.dimension('ngptsz'),) if (nw != self.nw or nspins != self.nspins or (ng != self.gd.get_size_of_global_array()).any()): raise IOError('Data has incompatible shapes.') # Test width (non-critical) sigma = tar['Width'] if ((sigma is None)!=(self.sigma is None) or # float <-> None (sigma is not None and self.sigma is not None and \ abs(sigma - self.sigma) > 1e-12)): # float -> float print('Warning: Width has been altered. (%s -> %s)' \ % (self.sigma, sigma)) self.sigma = sigma # Read frequencies self.omega_w[:] = tar.get('Frequency') # Read cumulative phase factors self.gamma_w[:] = tar.get('PhaseFactor') # Read average densities on master and distribute for s in range(self.nspins): all_Ant_G = tar.get('Average', s) self.gd.distribute(all_Ant_G, self.Ant_sG[s]) # Read fourier transforms on master and distribute for w in range(self.nw): for s in range(self.nspins): all_Fnt_G = tar.get('FourierTransform', w, s) self.gd.distribute(all_Fnt_G, self.Fnt_wsG[w, s]) # Close for good measure tar.close()
def read_old_gpw(filename): from gpaw.io.tar import Reader r = Reader(filename) positions = r.get('CartesianPositions') * Bohr numbers = r.get('AtomicNumbers') cell = r.get('UnitCell') * Bohr pbc = r.get('BoundaryConditions') tags = r.get('Tags') magmoms = r.get('MagneticMoments') energy = r.get('PotentialEnergy') * Hartree if r.has_array('CartesianForces'): forces = r.get('CartesianForces') * Hartree / Bohr else: forces = None atoms = Atoms(positions=positions, numbers=numbers, cell=cell, pbc=pbc) if tags.any(): atoms.set_tags(tags) if magmoms.any(): atoms.set_initial_magnetic_moments(magmoms) magmom = magmoms.sum() else: magmoms = None magmom = None atoms.calc = SinglePointDFTCalculator(atoms, energy=energy, forces=forces, magmoms=magmoms, magmom=magmom) kpts = [] if r.has_array('IBZKPoints'): for w, kpt, eps_n, f_n in zip(r.get('IBZKPointWeights'), r.get('IBZKPoints'), r.get('Eigenvalues'), r.get('OccupationNumbers')): kpts.append(SinglePointKPoint(w, kpt[0], kpt[1], eps_n[0], f_n[0])) atoms.calc.kpts = kpts return atoms
def calculate_energy(self, pd, chi0_swGG, cut_G): """Evaluate correlation energy from chi0 and the kernel fhxc""" ibzq2_q = [ np.dot(self.ibzq_qc[i] - pd.kd.bzk_kc[0], self.ibzq_qc[i] - pd.kd.bzk_kc[0]) for i in range(len(self.ibzq_qc)) ] qi = np.argsort(ibzq2_q)[0] G_G = pd.G2_qG[0]**0.5 # |G+q| if cut_G is not None: G_G = G_G[cut_G] nG = len(G_G) ns = len(chi0_swGG) if self.xc != 'RPA': r = Reader('fhxc_%s_%s_%s_%s.gpw' % (self.tag, self.xc, self.ecut_max, qi)) fv = r.get('fhxc_sGsG') if cut_G is not None: cut_sG = np.tile(cut_G, ns) cut_sG[len(cut_G):] += len(fv) / ns fv = fv.take(cut_sG, 0).take(cut_sG, 1) for s1 in range(ns): for s2 in range(ns): m1 = s1 * nG n1 = (s1 + 1) * nG m2 = s2 * nG n2 = (s2 + 1) * nG fv[m1:n1, m2:n2] *= G_G * G_G[:, np.newaxis] / 4 / np.pi if np.prod(self.unit_cells) > 1 and pd.kd.gamma: m1 = s1 * nG n1 = (s1 + 1) * nG m2 = s2 * nG n2 = (s2 + 1) * nG fv[m1, m2:n2] = 0.0 fv[m1:n1, m2] = 0.0 fv[m1, m2] = 1.0 else: fv = np.tile(np.eye(nG), (ns, ns)) if pd.kd.gamma: G_G[0] = 1.0 e_w = [] for chi0_sGG in np.swapaxes(chi0_swGG, 0, 1): if cut_G is not None: chi0_sGG = chi0_sGG.take(cut_G, 1).take(cut_G, 2) chi0v = np.zeros((ns * nG, ns * nG), dtype=complex) for s in range(ns): m = s * nG n = (s + 1) * nG chi0v[m:n, m:n] = chi0_sGG[s] / G_G / G_G[:, np.newaxis] chi0v *= 4 * np.pi del chi0_sGG e = 0.0 for l, weight in zip(self.l_l, self.weight_l): chiv = np.linalg.solve( np.eye(nG * ns) - l * np.dot(chi0v, fv), chi0v).real for s1 in range(ns): for s2 in range(ns): m1 = s1 * nG n1 = (s1 + 1) * nG m2 = s2 * nG n2 = (s2 + 1) * nG chiv_s1s2 = chiv[m1:n1, m2:n2] e -= np.trace(chiv_s1s2) * weight e += np.trace(chi0v.real) e_w.append(e) E_w = np.zeros_like(self.omega_w) self.blockcomm.all_gather(np.array(e_w), E_w) energy = np.dot(E_w, self.weight_w) / (2 * np.pi) return energy
def calculate_energy(self, pd, chi0_swGG, cut_G): """Evaluate correlation energy from chi0 and the kernel fhxc""" ibzq2_q = [np.dot(self.ibzq_qc[i] - pd.kd.bzk_kc[0], self.ibzq_qc[i] - pd.kd.bzk_kc[0]) for i in range(len(self.ibzq_qc))] qi = np.argsort(ibzq2_q)[0] G_G = pd.G2_qG[0]**0.5 # |G+q| if cut_G is not None: G_G = G_G[cut_G] nG = len(G_G) ns = len(chi0_swGG) if self.xc != 'RPA': r = Reader('fhxc_%s_%s_%s_%s.gpw' % (self.tag, self.xc, self.ecut_max, qi)) fv = r.get('fhxc_sGsG') if cut_G is not None: cut_sG = np.tile(cut_G, ns) cut_sG[len(cut_G):] += len(fv) / ns fv = fv.take(cut_sG, 0).take(cut_sG, 1) for s1 in range(ns): for s2 in range(ns): m1 = s1 * nG n1 = (s1 + 1) * nG m2 = s2 * nG n2 = (s2 + 1) * nG fv[m1:n1, m2:n2] *= G_G * G_G[:, np.newaxis] / 4 / np.pi if np.prod(self.unit_cells) > 1 and pd.kd.gamma: m1 = s1 * nG n1 = (s1 + 1) * nG m2 = s2 * nG n2 = (s2 + 1) * nG fv[m1, m2:n2] = 0.0 fv[m1:n1, m2] = 0.0 fv[m1, m2] = 1.0 else: fv = np.tile(np.eye(nG), (ns, ns)) if pd.kd.gamma: G_G[0] = 1.0 e_w = [] j = 0 for chi0_sGG in np.swapaxes(chi0_swGG, 0, 1): if cut_G is not None: chi0_sGG = chi0_sGG.take(cut_G, 1).take(cut_G, 2) chi0v = np.zeros((ns * nG, ns * nG), dtype=complex) for s in range(ns): m = s * nG n = (s + 1) * nG chi0v[m:n, m:n] = chi0_sGG[s] / G_G / G_G[:, np.newaxis] chi0v *= 4 * np.pi del chi0_sGG e = 0.0 for l, weight in zip(self.l_l, self.weight_l): chiv = np.linalg.solve(np.eye(nG * ns) - l * np.dot(chi0v, fv), chi0v).real for s1 in range(ns): for s2 in range(ns): m1 = s1 * nG n1 = (s1 + 1) * nG m2 = s2 * nG n2 = (s2 + 1) * nG chiv_s1s2 = chiv[m1:n1, m2:n2] e -= np.trace(chiv_s1s2) * weight e += np.trace(chi0v.real) e_w.append(e) E_w = np.zeros_like(self.omega_w) self.wcomm.all_gather(np.array(e_w), E_w) energy = np.dot(E_w, self.weight_w) / (2 * np.pi) return energy