def calculate(self, ecut): if self.xc != 'RPA': if isinstance(ecut, (float, int)): self.ecut_max = ecut else: self.ecut_max = max(ecut) if not os.path.isfile('fhxc_%s_%s_%s_0.gpw' % (self.tag, self.xc, self.ecut_max)): kernel = Kernel(self.calc, self.xc, self.ibzq_qc, self.fd, self.unit_cells, self.density_cut, self.ecut_max, self.tag, self.timer) kernel.calculate_fhxc() del kernel else: prnt('%s kernel already calculated' % self.xc, file=self.fd) prnt(file=self.fd) if self.calc.wfs.nspins == 1: spin = False else: spin = True e = RPACorrelation.calculate(self, ecut, spin=spin) return e
def calculate_q(self, chi0, pd, chi0_swGG, chi0_swxvG, chi0_swvv, Q_aGii, m1, m2, cut_G, A2_x): if chi0_swxvG is None: chi0_swxvG = range(2) # Not used chi0_swvv = range(2) # Not used chi0._calculate(pd, chi0_swGG[0], chi0_swxvG[0], chi0_swvv[0], Q_aGii, m1, m2, [0]) if len(chi0_swGG) == 2: chi0._calculate(pd, chi0_swGG[1], chi0_swxvG[1], chi0_swvv[1], Q_aGii, m1, m2, [1]) prnt('E_c(q) = ', end='', file=self.fd) chi0_swGG = chi0.redistribute(chi0_swGG, A2_x) if not pd.kd.gamma: e = self.calculate_energy(pd, chi0_swGG, cut_G) prnt('%.3f eV' % (e * Hartree), file=self.fd) self.fd.flush() else: e = 0.0 for v in range(3): chi0_swGG[:, :, 0] = chi0_swxvG[:, :, 0, v] chi0_swGG[:, :, :, 0] = chi0_swxvG[:, :, 1, v] chi0_swGG[:, :, 0, 0] = chi0_swvv[:, :, v, v] ev = self.calculate_energy(pd, chi0_swGG, cut_G) e += ev prnt('%.3f' % (ev * Hartree), end='', file=self.fd) if v < 2: prnt('/', end='', file=self.fd) else: prnt('eV', file=self.fd) self.fd.flush() e /= 3 return e
def calculate(self, ecut): if self.xc != 'RPA': if isinstance(ecut, (float, int)): self.ecut_max = ecut else: self.ecut_max = max(ecut) if not os.path.isfile('fhxc_%s_%s_%s_0.gpw' % (self.tag, self.xc, self.ecut_max)): kernel = Kernel(self.calc, self.xc, self.ibzq_qc, self.fd, self.unit_cells, self.density_cut, self.ecut_max, self.tag) kernel.calculate_fhxc() del kernel else: prnt('%s kernel already calculated' % self.xc, file=self.fd) prnt(file=self.fd) if self.calc.wfs.nspins == 1: spin = False else: spin = True e = RPACorrelation.calculate(self, ecut, spin=spin) return e
def calculate_q(self, chi0, pd, chi0_swGG, chi0_swxvG, chi0_swvv, Q_aGii, m1, m2, cut_G): if chi0_swxvG is None: chi0_swxvG = range(2) # Not used chi0_swvv = range(2) # Not used chi0._calculate(pd, chi0_swGG[0], chi0_swxvG[0], chi0_swvv[0], Q_aGii, m1, m2, [0]) if len(chi0_swGG) == 2: chi0._calculate(pd, chi0_swGG[1], chi0_swxvG[1], chi0_swvv[1], Q_aGii, m1, m2, [1]) prnt('E_c(q) = ', end='', file=self.fd) if not pd.kd.gamma: e = self.calculate_energy(pd, chi0_swGG, cut_G) prnt('%.3f eV' % (e * Hartree), file=self.fd) self.fd.flush() else: e = 0.0 for v in range(3): chi0_swGG[:, :, 0] = chi0_swxvG[:, :, 0, v] chi0_swGG[:, :, :, 0] = chi0_swxvG[:, :, 1, v] chi0_swGG[:, :, 0, 0] = chi0_swvv[:, :, v, v] ev = self.calculate_energy(pd, chi0_swGG, cut_G) e += ev prnt('%.3f' % (ev * Hartree), end='', file=self.fd) if v < 2: prnt('/', end='', file=self.fd) else: prnt('eV', file=self.fd) self.fd.flush() e /= 3 return e
def calculate_fhxc(self): prnt('Calculating %s kernel at %d eV cutoff' % (self.xc, self.ecut), file=self.fd) if self.xc[0] == 'r': self.calculate_rkernel() else: assert self.xc[0] == 'A' self.calculate_local_kernel()
def write(self): if self.world.rank == 0 and self.filename: fd = open(self.filename, 'w') prnt('#%9s %10s %10s %8s %12s' % ('q1', 'q2', 'q3', 'E_cut', 'E_c(q)'), file=fd) for energy_i, q_c in zip(self.energy_qi, self.ibzq_qc): for energy, ecut in zip(energy_i, self.ecut_i): prnt('%10.4f %10.4f %10.4f %8d %r' % (tuple(q_c) + (ecut * Hartree, energy * Hartree)), file=fd)
def calculate_local_kernel(self): # Standard ALDA exchange kernel # Use with care. Results are very difficult to converge # Sensitive to density_cut ns = self.calc.wfs.nspins gd = self.gd pd = self.pd cell_cv = gd.cell_cv icell_cv = 2 * np.pi * np.linalg.inv(cell_cv) vol = np.linalg.det(cell_cv) fxc_sg = ns * self.get_fxc_g(ns * self.n_g) fxc_sg[np.where(self.n_g < self.density_cut)] = 0.0 r_vg = gd.get_grid_point_coordinates() for iq in range(len(self.ibzq_qc)): Gvec_Gc = np.dot(pd.get_reciprocal_vectors(q=iq, add_q=False), cell_cv / (2 * np.pi)) npw = len(Gvec_Gc) l_pw_size = -(-npw // mpi.world.size) l_pw_range = range(mpi.world.rank * l_pw_size, min((mpi.world.rank + 1) * l_pw_size, npw)) fhxc_sGsG = np.zeros((ns * npw, ns * npw), dtype=complex) for s in range(ns): for iG in l_pw_range: for jG in range(npw): fxc = fxc_sg[s].copy() dG_c = Gvec_Gc[iG] - Gvec_Gc[jG] dG_v = np.dot(dG_c, icell_cv) dGr_g = gemmdot(dG_v, r_vg, beta=0.0) ft_fxc = gd.integrate(np.exp(-1j * dGr_g) * fxc) fhxc_sGsG[s * npw + iG, s * npw + jG] = ft_fxc mpi.world.sum(fhxc_sGsG) fhxc_sGsG /= vol Gq2_G = self.pd.G2_qG[iq] if (self.ibzq_qc[iq] == 0).all(): Gq2_G[0] = 1. vq_G = 4 * np.pi / Gq2_G fhxc_sGsG += np.tile(np.eye(npw) * vq_G, (ns, ns)) if mpi.rank == 0: w = Writer('fhxc_%s_%s_%s_%s.gpw' % (self.tag, self.xc, self.ecut, iq)) w.dimension('sG', ns * npw) w.add('fhxc_sGsG', ('sG', 'sG'), dtype=complex) w.fill(fhxc_sGsG) w.close() mpi.world.barrier() prnt(file=self.fd)
def __init__(self, lrtddft, index, d=0.001, txt=None, parallel=None, name=None): """ExcitedState object. parallel: Can be used to parallelize the numerical force calculation over images. """ FiniteDifferenceCalculator.__init__(self, lrtddft, d, txt, parallel) if type(index) == type(1): self.index = UnconstraintIndex(index) else: self.index = index self.name = name self.energy = None self.F_av = None prnt('#', self.index, file=self.txt) if name: prnt(('name=' + name), file=self.txt) prnt('# Force displacement:', self.d, file=self.txt) if self.parallel: prnt('#', self.parallel['world'].size, 'cores in total, ', self.parallel['mycomm'].size, 'cores per energy evaluation', file=self.txt)
def get_forces(self, atoms=None): """Get finite-difference forces""" if atoms is None: atoms = self.atoms if self.calculation_required(atoms, ['F_av']): atoms.set_calculator(self) # do the ground state calculation to set all # ranks to the same density to start with self.calculator.calculate(atoms) world = self.parallel['world'] txt = self.txt if world.rank > 0: txt = sys.stdout mycomm = self.parallel['mycomm'] ncalcs = self.parallel['ncalcs'] icalc = self.parallel['icalc'] F_av = np.zeros((len(atoms), 3)) i = 0 for ia, a in enumerate(self.atoms): for ic in range(3): # print "ncalcs", ncalcs, "i", i, "icalc",icalc if (i % ncalcs) == icalc: F_av[ia, ic] = numeric_force( atoms, ia, ic, self.d) / mycomm.size prnt('# rank', world.rank, '-> force', (str(ia) + 'xyz'[ic]), file=txt) i += 1 energy = np.array([0.]) # array needed for world.sum() if (i % ncalcs) == icalc: self.energy = None energy[0] = self.get_potential_energy(atoms) / mycomm.size prnt('# rank', world.rank, '-> energy', energy[0] * mycomm.size, file=txt) self.set_positions(atoms) world.sum(F_av) world.sum(energy) self.energy = energy[0] self.F_av = F_av if self.txt: prnt('Excited state forces in eV/Ang:', file=self.txt) symbols = self.atoms.get_chemical_symbols() for a, symbol in enumerate(symbols): prnt(('%3d %-2s %10.5f %10.5f %10.5f' % ((a, symbol) + tuple(self.F_av[a]))), file=self.txt) return self.F_av
def read(self): lines = open(self.filename).readlines()[1:] n = 0 self.energy_qi = [] nq = len(lines) // len(self.ecut_i) for q_c in self.ibzq_qc[:nq]: self.energy_qi.append([]) for ecut in self.ecut_i: q1, q2, q3, ec, energy = [float(x) for x in lines[n].split()] self.energy_qi[-1].append(energy / Hartree) n += 1 if (abs(q_c - (q1, q2, q3)).max() > 1e-4 or abs(int(ecut * Hartree) - ec) > 0): self.energy_qi = [] return prnt('Read %d q-points from file: %s' % (nq, self.filename), file=self.fd) prnt(file=self.fd)
def __init__(self, cell_cv, nk_c, txt=sys.stdout): self.nk_c = nk_c bigcell_cv = cell_cv * nk_c[:, np.newaxis] L_c = (np.linalg.inv(bigcell_cv)**2).sum(0)**-0.5 rc = 0.5 * L_c.min() prnt('Inner radius for %dx%dx%d Wigner-Seitz cell: %.3f Ang' % (tuple(nk_c) + (rc * Bohr, )), file=txt) self.a = 5 / rc prnt('Range-separation parameter: %.3f Ang^-1' % (self.a / Bohr), file=txt) # nr_c = [get_efficient_fft_size(2 * int(L * self.a * 1.5)) nr_c = [get_efficient_fft_size(2 * int(L * self.a * 3.0)) for L in L_c] prnt('FFT size for calculating truncated Coulomb: %dx%dx%d' % tuple(nr_c), file=txt) self.gd = GridDescriptor(nr_c, bigcell_cv, comm=mpi.serial_comm) v_R = self.gd.empty() v_i = v_R.ravel() pos_iv = self.gd.get_grid_point_coordinates().reshape((3, -1)).T corner_jv = np.dot(np.indices((2, 2, 2)).reshape((3, 8)).T, bigcell_cv) for i, pos_v in enumerate(pos_iv): r = ((pos_v - corner_jv)**2).sum(axis=1).min()**0.5 if r == 0: v_i[i] = 2 * self.a / pi**0.5 else: v_i[i] = erf(self.a * r) / r self.K_Q = np.fft.fftn(v_R) * self.gd.dv
def get_forces(self, atoms=None): """Get finite-difference forces""" if atoms is None: atoms = self.atoms if self.calculation_required(atoms, ['F_av']): atoms.set_calculator(self) # do the ground state calculation to set all # ranks to the same density to start with self.calculator.calculate(atoms) world = self.parallel['world'] txt = self.txt if world.rank > 0: txt = sys.stdout mycomm = self.parallel['mycomm'] ncalcs = self.parallel['ncalcs'] icalc = self.parallel['icalc'] F_av = np.zeros((len(atoms), 3)) i = 0 for ia, a in enumerate(self.atoms): for ic in range(3): if (i % ncalcs) == icalc: F_av[ia, ic] = numeric_force( atoms, ia, ic, self.d) / mycomm.size prnt('# rank', world.rank, '-> force', (str(ia) + 'xyz'[ic]), file=txt) i += 1 energy = np.array([0.]) # array needed for world.sum() if (i % ncalcs) == icalc: self.energy = None energy[0] = self.get_potential_energy(atoms) / mycomm.size prnt('# rank', world.rank, '-> energy', energy[0] * mycomm.size, file=txt) self.set_positions(atoms) world.sum(F_av) world.sum(energy) self.energy = energy[0] self.F_av = F_av if self.txt: prnt('Excited state forces in eV/Ang:', file=self.txt) symbols = self.atoms.get_chemical_symbols() for a, symbol in enumerate(symbols): prnt(('%3d %-2s %10.5f %10.5f %10.5f' % ((a, symbol) + tuple(self.F_av[a]))), file=self.txt) return self.F_av
def __init__(self, cell_cv, nk_c, txt=sys.stdout): self.nk_c = nk_c bigcell_cv = cell_cv * nk_c[:, np.newaxis] L_c = (np.linalg.inv(bigcell_cv)**2).sum(0)**-0.5 rc = 0.5 * L_c.min() prnt('Inner radius for %dx%dx%d Wigner-Seitz cell: %.3f Ang' % (tuple(nk_c) + (rc * Bohr,)), file=txt) self.a = 5 / rc prnt('Range-separation parameter: %.3f Ang^-1' % (self.a / Bohr), file=txt) # nr_c = [get_efficient_fft_size(2 * int(L * self.a * 1.5)) nr_c = [get_efficient_fft_size(2 * int(L * self.a * 3.0)) for L in L_c] prnt('FFT size for calculating truncated Coulomb: %dx%dx%d' % tuple(nr_c), file=txt) self.gd = GridDescriptor(nr_c, bigcell_cv, comm=mpi.serial_comm) v_R = self.gd.empty() v_i = v_R.ravel() pos_iv = self.gd.get_grid_point_coordinates().reshape((3, -1)).T corner_jv = np.dot(np.indices((2, 2, 2)).reshape((3, 8)).T, bigcell_cv) for i, pos_v in enumerate(pos_iv): r = ((pos_v - corner_jv)**2).sum(axis=1).min()**0.5 if r == 0: v_i[i] = 2 * self.a / pi**0.5 else: v_i[i] = erf(self.a * r) / r self.K_Q = np.fft.fftn(v_R) * self.gd.dv
def __init__(self, lrtddft, d=0.001, txt=None, parallel=None): """Finite difference calculator for LrTDDFT. parallel: Can be used to parallelize the numerical force calculation over images """ self.timer = Timer() self.atoms = None world = mpi.world if lrtddft is not None: self.lrtddft = lrtddft self.calculator = self.lrtddft.calculator self.atoms = self.calculator.atoms if self.calculator.initialized: world = self.calculator.wfs.world if txt is None: self.txt = self.lrtddft.txt else: self.txt, firsttime = initialize_text_stream( txt, world.rank) prnt('#', self.__class__.__name__, version, file=self.txt) self.d = d self.parallel = { 'world' : world, 'mycomm' : world, 'ncalcs' : 1, 'icalc' : 0 } if world.size < 2: if parallel > 0: prnt('#', (self.__class__.__name__ + ':'), 'Serial calculation, keyword parallel ignored.', file=self.txt) elif parallel > 0: mycomm, ncalcs, icalc = distribute_cpus(parallel, world) if type(ncalcs) != type(1): # this is ase < r3431 ncalcs = world.size / parallel self.parallel = { 'world' : world, 'mycomm' : mycomm, 'ncalcs' : ncalcs, 'icalc' : icalc } self.calculator.set(communicator=mycomm)
def __init__(self, lrtddft, d=0.001, txt=None, parallel=None): """Finite difference calculator for LrTDDFT. parallel: Can be used to parallelize the numerical force calculation over images """ self.timer = Timer() self.atoms = None world = mpi.world if lrtddft is not None: self.lrtddft = lrtddft self.calculator = self.lrtddft.calculator self.atoms = self.calculator.atoms if self.calculator.initialized: world = self.calculator.wfs.world if txt is None: self.txt = self.lrtddft.txt else: self.txt = get_txt(txt, world.rank) prnt('#', self.__class__.__name__, version, file=self.txt) self.d = d self.parallel = { 'world': world, 'mycomm': world, 'ncalcs': 1, 'icalc': 0} if world.size < 2: if parallel > 0: prnt('#', (self.__class__.__name__ + ':'), 'Serial calculation, keyword parallel ignored.', file=self.txt) elif parallel > 0: mycomm, ncalcs, icalc = distribute_cpus(parallel, world) if type(ncalcs) != type(1): # this is ase < r3431 ncalcs = world.size / parallel self.parallel = {'world': world, 'mycomm': mycomm, 'ncalcs': ncalcs, 'icalc': icalc} self.calculator.set(communicator=mycomm)
def calculate_q(self, chi0, pd, chi0_wGG, chi0_wxvG, Q_aGii, m1, m2, cut_G): chi0._calculate(pd, chi0_wGG, chi0_wxvG, Q_aGii, m1, m2) prnt('E_c(q) = ', end='', file=self.fd) if not pd.kd.gamma: e = self.calculate_energy(pd, chi0_wGG, cut_G) prnt('%.3f eV' % (e * Hartree), flush=True, file=self.fd) else: e = 0.0 for v in range(3): chi0_wGG[:, 0] = chi0_wxvG[:, 0, v] chi0_wGG[:, :, 0] = chi0_wxvG[:, 1, v] ev = self.calculate_energy(pd, chi0_wGG, cut_G) e += ev prnt('%.3f' % (ev * Hartree), end='', file=self.fd) if v < 2: prnt('/', end='', file=self.fd) else: prnt(' eV', flush=True, file=self.fd) e /= 3 return e
def calculate(self): kd = self.calc.wfs.kd nspins = self.calc.wfs.nspins for s in range(nspins): for i, k1 in enumerate(self.kpts): K1 = kd.ibz2bz_k[k1] kpt1 = self.get_k_point(s, K1, *self.bands) self.f_sin[s, i] = kpt1.f_n for kpt2 in self.mykpts: if kpt2.s == s: self.calculate_q(i, kpt1, kpt2) self.calculate_paw_exx_corrections(i, kpt1) self.world.sum(self.exxvv_sin) # Calculate total energy if we have everything needed: if (len(self.kpts) == kd.nibzkpts and self.bands[0] == 0 and self.bands[1] >= self.nocc2): exxvv_i = (self.exxvv_sin * self.f_sin).sum(axis=2).sum(axis=0) exxvc_i = 2 * (self.exxvc_sin * self.f_sin).sum(axis=2).sum(axis=0) self.exxvv = np.dot(kd.weight_k[self.kpts], exxvv_i) / nspins self.exxvc = np.dot(kd.weight_k[self.kpts], exxvc_i) / nspins self.exx = self.exxvv + self.exxvc + self.exxcc prnt('Exact exchange energy:', file=self.fd) for kind, exx in [('valence-valence', self.exxvv), ('valence-core', self.exxvc), ('core-core', self.exxcc), ('total', self.exx)]: prnt('%16s%11.3f eV' % (kind + ':', exx * Hartree), file=self.fd) self.exc = self.calculate_hybrid_correction() exx_sin = self.exxvv_sin + self.exxvc_sin prnt('EXX eigenvalue contributions in eV:', file=self.fd) prnt(np.array_str(exx_sin * Hartree, precision=3), file=self.fd)
def extrapolate(self, e_i): prnt('Extrapolated energies:', file=self.fd) ex_i = [] for i in range(len(e_i) - 1): e1, e2 = e_i[i:i + 2] x1, x2 = self.ecut_i[i:i + 2]**-1.5 ex = (e1 * x2 - e2 * x1) / (x2 - x1) ex_i.append(ex) prnt(' %4.0f -%4.0f: %5.3f eV' % (self.ecut_i[i] * Hartree, self.ecut_i[i + 1] * Hartree, ex * Hartree), file=self.fd, flush=True) prnt(file=self.fd) return e_i * Hartree
def log(self, *args, **kwargs): prnt(file=self.fd, *args, **kwargs) self.fd.flush()
try: ea = data[name].get('dissociation energy', np.nan) * kcal / mol dist = molecule(name, data=data).get_distance(0, 1) freq = data[name].get('harmonic frequency', np.nan) t = np.nan except KeyError: ea = np.nan dist = np.nan freq = np.nan t = np.nan A.append((ea, dist, freq, t)) return np.array(A).T E0, D0, F0, T0 = analyse() try: E1, D1, F1, T1 = analyse() except KeyError: E1 = E0 D1 = D0 F1 = F0 T1 = T0 fd = open('%s.csv' % db, 'w') prnt('# Atomization energies (E), distances (d), frequencies (f) and time (t): %s' % db, file=fd) prnt('# name (N), E(N; not relaxed), E(N), d(N), F(N; not relaxed), F(N), t(N; not relaxed) [sec]', file=fd) for name, e0, e1, d1, f0, f1, t0, in zip(molecule_names, E0, E1, D1, F0, F1, T0): prnt('%11s, %7.3f, %7.3f, %7.3f, %7.1f, %7.1f, %7.1f' % (name, e0, e1, d1, f0, f1, t0), file=fd)
def __init__(self, calc, xc=None, kpts=None, bands=None, ecut=None, omega=None, world=mpi.world, txt=sys.stdout, timer=None): PairDensity.__init__(self, calc, ecut, world=world, txt=txt, timer=timer) if xc is None or xc == 'EXX': self.exx_fraction = 1.0 xc = XC(XCNull()) elif xc == 'PBE0': self.exx_fraction = 0.25 xc = XC('HYB_GGA_XC_PBEH') elif xc == 'HSE03': omega = 0.106 self.exx_fraction = 0.25 xc = XC('HYB_GGA_XC_HSE03') elif xc == 'HSE06': omega = 0.11 self.exx_fraction = 0.25 xc = XC('HYB_GGA_XC_HSE06') elif xc == 'B3LYP': self.exx_fraction = 0.2 xc = XC('HYB_GGA_XC_B3LYP') self.xc = xc self.omega = omega self.exc = np.nan # density dependent part of xc-energy self.kpts = select_kpts(kpts, self.calc) if bands is None: # Do all occupied bands: bands = [0, self.nocc2] prnt('Calculating exact exchange contributions for band index', '%d-%d' % (bands[0], bands[1] - 1), file=self.fd) prnt('for IBZ k-points with indices:', ', '.join(str(i) for i in self.kpts), file=self.fd) self.bands = bands if self.ecut is None: self.ecut = self.calc.wfs.pd.ecut prnt('Plane-wave cutoff: %.3f eV' % (self.ecut * Hartree), file=self.fd) shape = (self.calc.wfs.nspins, len(self.kpts), bands[1] - bands[0]) self.exxvv_sin = np.zeros(shape) # valence-valence exchange energies self.exxvc_sin = np.zeros(shape) # valence-core exchange energies self.f_sin = np.empty(shape) # occupation numbers # The total EXX energy will not be calculated if we are only # interested in a few eigenvalues for a few k-points self.exx = np.nan # total EXX energy self.exxvv = np.nan # valence-valence self.exxvc = np.nan # valence-core self.exxcc = 0.0 # core-core self.mysKn1n2 = None # my (s, K, n1, n2) indices self.distribute_k_points_and_bands(0, self.nocc2) # All occupied states: self.mykpts = [ self.get_k_point(s, K, n1, n2) for s, K, n1, n2 in self.mysKn1n2 ] prnt('Using Wigner-Seitz truncated coulomb interaction.', file=self.fd) self.wstc = WignerSeitzTruncatedCoulomb(self.calc.wfs.gd.cell_cv, self.calc.wfs.kd.N_c, self.fd) self.iG_qG = {} # cache # PAW matrices: self.V_asii = [] # valence-valence correction self.C_aii = [] # valence-core correction self.initialize_paw_exx_corrections()
collection = Collection() if len(sys.argv) == 1: category = 'fcc' collection = Collection() names = collection.names elif len(sys.argv) == 2: category = sys.argv[1] collection = Collection(category=category) names = collection.names else: category = sys.argv[1] collection = Collection(category=category) names = [sys.argv[2]] fd = open('doi_' + category + '_raw.csv', 'w') for name in names: e = 0.0 e0 = 0.0 b0 = 0.0 b1 = 0.0 if name in ['N', 'Hg']: e = np.nan # number of unit formulas per cell nufpc = len(collection[name]) / len(string2symbols(name)) v = collection[name].get_volume() v = v / nufpc if not np.isnan(e): prnt('%s, %7.3f, %8.4f, %8.4f, %8.4f, %8.4f' % (name, e, e0, v, b0, b1), file=fd)
def log(self, *args, **kwargs): prnt(file=self.logfile, *args, **kwargs)
print 'bq', d.name ea = ea + d.energy else: print 'molecule', d.name ea = - d.energy dist = ((d.positions[0] - d.positions[-1])**2).sum()**0.5 t = d.time except (KeyError, ValueError): ea = np.nan dist = np.nan t = np.nan A.append((ea, dist, t)) return np.array(A).T E0, D0, T0 = analyse(calc, 0) try: E1, D1, T1 = analyse(calc, 1) except KeyError: E1 = E0 D1 = D0 T1 = T0 fd = open('%s.csv' % db, 'w') prnt('# Atomization energies (E), distances (d) and time (t): %s %s' % (calc, db), file=fd) prnt('# name (N), E(N; not relaxed), E(N), d(N), t(N; not relaxed) [sec]', file=fd) for name, e0, e1, d1, t0, in zip(molecule_names, E0, E1, D1, T0): prnt('%21s, %7.3f, %7.3f, %7.3f, %7.1f' % (name, e0, e1, d1, t0), file=fd)
def calculate_rkernel(self): gd = self.gd ng_c = gd.N_c cell_cv = gd.cell_cv icell_cv = 2 * np.pi * np.linalg.inv(cell_cv) vol = np.linalg.det(cell_cv) ns = self.calc.wfs.nspins n_g = self.n_g # density on rough grid fx_g = ns * self.get_fxc_g(n_g) # local exchange kernel qc_g = (-4 * np.pi * ns / fx_g)**0.5 # cutoff functional flocal_g = qc_g**3 * fx_g / (6 * np.pi**2) # ren. x-kernel for r=r' Vlocal_g = 2 * qc_g / np.pi # ren. Hartree kernel for r=r' ng = np.prod(ng_c) # number of grid points r_vg = gd.get_grid_point_coordinates() rx_g = r_vg[0].flatten() ry_g = r_vg[1].flatten() rz_g = r_vg[2].flatten() prnt(' %d grid points and %d plane waves at the Gamma point' % (ng, self.pd.ngmax), file=self.fd) # Unit cells R_Rv = [] weight_R = [] nR_v = self.unit_cells nR = np.prod(nR_v) for i in range(-nR_v[0] + 1, nR_v[0]): for j in range(-nR_v[1] + 1, nR_v[1]): for h in range(-nR_v[2] + 1, nR_v[2]): R_Rv.append(i * cell_cv[0] + j * cell_cv[1] + h * cell_cv[2]) weight_R.append((nR_v[0] - abs(i)) * (nR_v[1] - abs(j)) * (nR_v[2] - abs(h)) / float(nR)) if nR > 1: # with more than one unit cell only the exchange kernel is # calculated on the grid. The bare Coulomb kernel is added # in PW basis and Vlocal_g only the exchange part dv = self.calc.density.gd.dv gc = (3 * dv / 4 / np.pi)**(1 / 3.) Vlocal_g -= 2 * np.pi * gc**2 / dv prnt(' Lattice point sampling: ' + '(%s x %s x %s)^2 ' % (nR_v[0], nR_v[1], nR_v[2]) + ' Reduced to %s lattice points' % len(R_Rv), file=self.fd) l_g_size = -(-ng // mpi.world.size) l_g_range = range(mpi.world.rank * l_g_size, min((mpi.world.rank + 1) * l_g_size, ng)) fhxc_qsGr = {} for iq in range(len(self.ibzq_qc)): fhxc_qsGr[iq] = np.zeros( (ns, len(self.pd.G2_qG[iq]), len(l_g_range)), dtype=complex) inv_error = np.seterr() np.seterr(invalid='ignore') np.seterr(divide='ignore') t0 = time() # Loop over Lattice points for i, R_v in enumerate(R_Rv): # Loop over r'. f_rr and V_rr are functions of r (dim. as r_vg[0]) if i == 1: prnt(' Finished 1 cell in %s seconds' % int(time() - t0) + ' - estimated %s seconds left' % int( (len(R_Rv) - 1) * (time() - t0)), file=self.fd) self.fd.flush() if len(R_Rv) > 5: if (i + 1) % (len(R_Rv) / 5 + 1) == 0: prnt(' Finished %s cells in %s seconds' % (i, int(time() - t0)) + ' - estimated %s seconds left' % int( (len(R_Rv) - i) * (time() - t0) / i), file=self.fd) self.fd.flush() for g in l_g_range: rx = rx_g[g] + R_v[0] ry = ry_g[g] + R_v[1] rz = rz_g[g] + R_v[2] # |r-r'-R_i| rr = ((r_vg[0] - rx)**2 + (r_vg[1] - ry)**2 + (r_vg[2] - rz)**2)**0.5 n_av = (n_g + n_g.flatten()[g]) / 2. fx_g = ns * self.get_fxc_g(n_av, index=g) qc_g = (-4 * np.pi * ns / fx_g)**0.5 x = qc_g * rr osc_x = np.sin(x) - x * np.cos(x) f_rr = fx_g * osc_x / (2 * np.pi**2 * rr**3) if nR > 1: # include only exchange part of the kernel here V_rr = (sici(x)[0] * 2 / np.pi - 1) / rr else: # include the full kernel (also hartree part) V_rr = (sici(x)[0] * 2 / np.pi) / rr # Terms with r = r' if (np.abs(R_v) < 0.001).all(): tmp_flat = f_rr.flatten() tmp_flat[g] = flocal_g.flatten()[g] f_rr = tmp_flat.reshape(ng_c) tmp_flat = V_rr.flatten() tmp_flat[g] = Vlocal_g.flatten()[g] V_rr = tmp_flat.reshape(ng_c) del tmp_flat f_rr[np.where(n_av < self.density_cut)] = 0.0 V_rr[np.where(n_av < self.density_cut)] = 0.0 f_rr *= weight_R[i] V_rr *= weight_R[i] # r-r'-R_i r_r = np.array([r_vg[0] - rx, r_vg[1] - ry, r_vg[2] - rz]) # Fourier transform of r for iq, q in enumerate(self.ibzq_qc): q_v = np.dot(q, icell_cv) e_q = np.exp(-1j * gemmdot(q_v, r_r, beta=0.0)) f_q = self.pd.fft((f_rr + V_rr) * e_q, iq) * vol / ng fhxc_qsGr[iq][0, :, g - l_g_range[0]] += f_q if ns == 2: f_q = self.pd.fft(V_rr * e_q, iq) * vol / ng fhxc_qsGr[iq][1, :, g - l_g_range[0]] += f_q mpi.world.barrier() np.seterr(**inv_error) for iq, q in enumerate(self.ibzq_qc): npw = len(self.pd.G2_qG[iq]) fhxc_sGsG = np.zeros((ns * npw, ns * npw), complex) l_pw_size = -(-npw // mpi.world.size) # parallelize over PW below l_pw_range = range(mpi.world.rank * l_pw_size, min((mpi.world.rank + 1) * l_pw_size, npw)) if mpi.world.size > 1: # redistribute grid and plane waves in fhxc_qsGr[iq] bg1 = BlacsGrid(mpi.world, 1, mpi.world.size) bg2 = BlacsGrid(mpi.world, mpi.world.size, 1) bd1 = bg1.new_descriptor(npw, ng, npw, -(-ng / mpi.world.size)) bd2 = bg2.new_descriptor(npw, ng, -(-npw / mpi.world.size), ng) fhxc_Glr = np.zeros((len(l_pw_range), ng), dtype=complex) if ns == 2: Koff_Glr = np.zeros((len(l_pw_range), ng), dtype=complex) r = Redistributor(bg1.comm, bd1, bd2) r.redistribute(fhxc_qsGr[iq][0], fhxc_Glr, npw, ng) if ns == 2: r.redistribute(fhxc_qsGr[iq][1], Koff_Glr, npw, ng) else: fhxc_Glr = fhxc_qsGr[iq][0] if ns == 2: Koff_Glr = fhxc_qsGr[iq][1] # Fourier transform of r' for iG in range(len(l_pw_range)): f_g = fhxc_Glr[iG].reshape(ng_c) f_G = self.pd.fft(f_g.conj(), iq) * vol / ng fhxc_sGsG[l_pw_range[0] + iG, :npw] = f_G.conj() if ns == 2: v_g = Koff_Glr[iG].reshape(ng_c) v_G = self.pd.fft(v_g.conj(), iq) * vol / ng fhxc_sGsG[npw + l_pw_range[0] + iG, :npw] = v_G.conj() if ns == 2: # f_00 = f_11 and f_01 = f_10 fhxc_sGsG[:npw, npw:] = fhxc_sGsG[npw:, :npw] fhxc_sGsG[npw:, npw:] = fhxc_sGsG[:npw, :npw] mpi.world.sum(fhxc_sGsG) fhxc_sGsG /= vol if mpi.rank == 0: w = Writer('fhxc_%s_%s_%s_%s.gpw' % (self.tag, self.xc, self.ecut, iq)) w.dimension('sG', ns * npw) w.add('fhxc_sGsG', ('sG', 'sG'), dtype=complex) if nR > 1: # add Hartree kernel evaluated in PW basis Gq2_G = self.pd.G2_qG[iq] if (q == 0).all(): Gq2_G[0] = 1. vq_G = 4 * np.pi / Gq2_G fhxc_sGsG += np.tile(np.eye(npw) * vq_G, (ns, ns)) w.fill(fhxc_sGsG) w.close() mpi.world.barrier() prnt(file=self.fd)
def update(self, atoms=None, properties=['energy', 'forces']): if not self.calculation_required(atoms, properties): return if atoms is None: atoms = self.calculator.get_atoms() self.results['energy'] = self.calculator.get_potential_energy(atoms) self.results['forces'] = self.calculator.get_forces(atoms) self.atoms = atoms.copy() if self.vdwradii is not None: # external vdW radii vdwradii = self.vdwradii assert(len(atoms) == len(vdwradii)) else: vdwradii = [] for atom in atoms: self.vdwradii.append(vdWDB_Grimme06jcc[atom.symbol][1]) if self.hirshfeld == None: volume_ratios = [1.] * len(atoms) elif hasattr(self.hirshfeld,'__len__'): # a list assert(len(atoms) == len(self.hirshfeld)) volume_ratios = self.hirshfeld else: # should be an object self.hirshfeld.initialize() volume_ratios = self.hirshfeld.get_effective_volume_ratios() # correction for effective C6 na = len(atoms) C6eff_a = np.empty((na)) alpha_a = np.empty((na)) R0eff_a = np.empty((na)) for a, atom in enumerate(atoms): # free atom values alpha_a[a], C6eff_a[a] = self.vdWDB_alphaC6[atom.symbol] # correction for effective C6 C6eff_a[a] *= Hartree * volume_ratios[a]**2 * Bohr**6 R0eff_a[a] = vdwradii[a] * volume_ratios[a]**(1./3.) C6eff_aa = np.empty((na, na)) for a in range(na): for b in range(a, na): C6eff_aa[a, b] = (2 * C6eff_a[a] * C6eff_a[b] / (alpha_a[b] / alpha_a[a] * C6eff_a[a] + alpha_a[a] / alpha_a[b] * C6eff_a[b] )) C6eff_aa[b, a] = C6eff_aa[a, b] # PBC pbc_c = atoms.get_pbc() cell_c = atoms.get_cell() Rcell_c = np.sqrt(np.sum(cell_c**2, axis=1)) ncells_c = np.ceil(np.where(pbc_c, 1. + self.Rmax / Rcell_c, 1)) ncells_c = np.array(ncells_c, dtype=int) positions = atoms.get_positions() EvdW = 0.0 forces = 0. * self.results['forces'] # loop over all atoms in the cell for ia, posa in enumerate(positions): # loop over all atoms in the cell (and neighbour cells for PBC) for ib, posb in enumerate(positions): # loops over neighbour cells for ix in range(-ncells_c[0] + 1, ncells_c[0]): for iy in range(-ncells_c[1] + 1, ncells_c[1]): for iz in range(-ncells_c[2] + 1, ncells_c[2]): i_c = np.array([ix, iy, iz]) diff = posb + np.dot(i_c, cell_c) - posa r2 = np.dot(diff, diff) r6 = r2**3 r = np.sqrt(r2) if r > 1.e-10 and r < self.Rmax: Edamp, Fdamp = self.damping(r, R0eff_a[ia], R0eff_a[ib], d=self.d, sR=self.sR) EvdW -= (Edamp * C6eff_aa[ia, ib] / r6 ) # we neglect the C6eff contribution to the # forces forces[ia] -= ((Fdamp - 6 * Edamp / r) * C6eff_aa[ia, ib] / r6 * diff / r ) self.results['energy'] += EvdW / 2. # double counting self.results['forces'] += forces / 2. # double counting if self.txt: prnt(('\n' + self.__class__.__name__), file=self.txt) prnt('vdW correction: %g' % (EvdW / 2.), file=self.txt) prnt('Energy: %g' % self.results['energy'], file=self.txt) prnt('\nForces in eV/Ang:', file=self.txt) c = Hartree / Bohr symbols = self.atoms.get_chemical_symbols() for ia, symbol in enumerate(symbols): prnt('%3d %-2s %10.5f %10.5f %10.5f' % ((ia, symbol) + tuple(self.results['forces'][ia])), file=self.txt)
A.append((ea, dist)) return np.array(A).T En0, Dn0 = analyse('nwchem', 0) En1, Dn1 = analyse('nwchem', 1) Eg0, Dg0 = analyse('gpaw', 0) Eg1, Dg1 = analyse('gpaw', 1) print(abs(Eg0 - En0).max(), abs(Eg0 - En0).mean()) print(abs(Eg1 - En1).max(), abs(Eg1 - En1).mean()) print(abs(Dg0 - Dn0).max(), abs(Dg0 - Dn0).mean()) print(abs(Dg1 - Dn1).max(), abs(Dg1 - Dn1).mean()) fd = open('g2-1.csv', 'w') prnt('# Atomization energies and distances. N: NWChem, G: GPAW', file=fd) prnt('# name, E(N, not relaxed), E(N), E(G)-E(N), d(N), d(G)-d(N)', file=fd) for name, en0, en1, eg1, dn1, dg1 in zip(molecule_names, En0, En1, Eg1, Dn1, Dg1): prnt('%11s, %7.3f, %7.3f, %7.3f, %7.3f, %7.3f' % (name, en0, en1, eg1 - en1, dn1, dg1 - dn1), file=fd) # these results are calculated at relaxed geometries ref = {'distance': {'NH3': 1.0212028325017757, 'S2': 1.909226444930773, 'SiH2_s3B1d': 1.4959758117701643, 'CH3OH': 1.103031397032791, 'SiH4': 1.492599477296688, 'Si2H6': 3.1894770187147787, 'PH3': 1.4301222209112225, 'PH2': 1.4346717268375369, 'HF': 0.93024767766719751, 'O2': 1.2177518292845226, 'SiH3': 1.4944876788686847, 'NH': 1.0495566124276352, 'SH2': 1.3513837051001727, 'ClO': 1.5787435668567111, 'H2O2': 1.8958330716525236, 'NO': 1.156790619328925, 'ClF': 1.6500936428996131, 'LiH': 1.6056281159928836, 'HCO': 1.134630847589132, 'CH3': 1.0857934634048991, 'CH4': 1.0954690924956099, 'Cl2': 2.0044430187644329, 'HOCl': 1.7084164068894601, 'SiH2_s1A1d': 1.5369100463950582, 'SiO': 1.5267775155499548, 'F2': 1.4131037387967056, 'P2': 1.9038007151393095, 'Si2': 2.2844499935377716, 'CH': 1.135943649633214, 'CO': 1.1353228578574415, 'CN': 1.1734204501040257, 'LiF': 1.5781425105489659, 'Na2': 3.0849004417809258, 'SO2': 1.4536010904565573, 'NaCl': 2.375956045377166, 'Li2': 2.7269446448266184, 'NH2': 1.0360313462587714, 'CS': 1.5453598419904586, 'C2H6': 2.1839921464514007, 'N2': 1.1020010395108386, 'C2H4': 2.1196102605939493, 'HCN': 1.074902699795437, 'C2H2': 1.0701025663671189, 'CH2_s3B1d': 1.0846126602770281, 'CH3Cl': 1.0934062531916822, 'BeH': 1.3549994786114516, 'CO2': 1.1705025664593323, 'CH3SH': 1.0951914666413829, 'OH': 0.98302300558682143, 'N2H4': 1.9949378750277829, 'H2O': 0.9689957468077689, 'SO': 1.5015729306543228, 'CH2_s1A1d': 1.1216809054426011, 'H2CO': 2.0340405586023551, 'HCl': 1.2882940110553078}, 'energy': {'NH3': -1537.8943922528292, 'S2': -21662.654140653412, 'SiH2_s3B1d': -7903.3690892881705, 'Li': -203.05091256761085, 'CH3OH': -3146.7647944133632, 'SiH4': -7938.4648222008409, 'Si2H6': -15845.082177930506, 'PH3': -9333.4084018049416, 'PH2': -9316.1298787915111, 'HF': -2732.0742553639361, 'O2': -4088.7283614591165, 'SiH3': -7920.9111544133084, 'NH': -1501.4257523508722, 'Be': -398.09853859103947, 'SH2': -10863.938964816221, 'ClO': -14561.296690949923, 'H2O2': -4121.946252450156, 'NO': -3532.6917094247037, 'ClF': -15231.961288082202, 'LiH': -218.97262833348015, 'HCO': -3096.2005211539013, 'CH3': -1082.8017329696315, 'CH4': -1101.1776994482279, 'Cl2': -25035.886547435726, 'Na': -4412.8227996808337, 'HOCl': -14578.981322327132, 'SiH2_s1A1d': -7904.0726269700554, 'SiO': -9920.2118092650708, 'F2': -5426.9009851655201, 'P2': -18569.7100395737, 'Si2': -15744.418687547124, 'C': -1028.5471962651873, 'CH': -1045.8247164754753, 'CO': -3081.4550529867706, 'CN': -2521.0913000695346, 'F': -2712.30655836285, 'H': -13.60405569717515, 'LiF': -2921.3671571474624, 'O': -2041.2483769244884, 'N': -1483.981485107872, 'Na2': -8826.410126700297, 'P': -9282.2144876505899, 'Si': -7870.4445140229245, 'SO2': -14923.501322516569, 'NaCl': -16933.432926277521, 'Li2': -406.96985635618387, 'NH2': -1519.3756700462491, 'CS': -11865.161113573042, 'C2H6': -2169.7998017018276, 'N2': -2978.5280844918202, 'C2H4': -2136.2951883618102, 'HCN': -2540.2803982015039, 'C2H2': -2102.2901648364796, 'CH2_s3B1d': -1064.1920578821023, 'CH3Cl': -13603.223029214254, 'BeH': -414.1082135671578, 'CO2': -5129.0868582477142, 'CH3SH': -11932.535768470407, 'OH': -2059.6213922996608, 'Cl': -12516.517962625088, 'S': -10828.826656949115, 'N2H4': -3042.0346586048404, 'H2O': -2078.6212796010145, 'SO': -12876.201520592005, 'CH2_s1A1d': -1063.5161597336582, 'H2CO': -3113.7397623037459, 'HCl': -12534.742429020402}, 'ea': {'NH3': 13.100740053431537, 'S2': 5.0008267551820609, 'SiH2_s3B1d': 5.7164638708964048, 'CH3OH': 22.552998434986876, 'SiH4': 13.604085389217289, 'Si2H6': 22.568815701608401, 'PH3': 10.381747062827344, 'PH2': 6.7072797465716576, 'HF': 6.1636413039109357, 'O2': 6.2316076101396902, 'SiH3': 9.654473298859557, 'NH': 3.8402115458250137, 'SH2': 7.9041964727566665, 'ClO': 3.5303514003462624, 'H2O2': 12.241387206829131, 'NO': 7.4618473923433157, 'ClF': 3.1367670942636323, 'LiH': 2.3176600686941526, 'HCO': 12.800892267050585, 'CH3': 13.442369612918583, 'CH4': 18.214280394339767, 'Cl2': 2.8506221855495824, 'HOCl': 7.6109270803808613, 'SiH2_s1A1d': 6.4200015527812866, 'SiO': 8.5189183176571532, 'F2': 2.2878684398201585, 'P2': 5.2810642725198704, 'Si2': 3.5296595012750913, 'CH': 3.6734645131127763, 'CO': 11.659479797095173, 'CN': 8.5626186964755107, 'LiF': 6.009686217001672, 'Na2': 0.7645273386297049, 'SO2': 12.177911718477844, 'NaCl': 4.0921639715998026, 'Li2': 0.86803122096216612, 'NH2': 8.1860735440266126, 'CS': 7.7872603587384219, 'C2H6': 31.081074988401724, 'N2': 10.565114276076201, 'C2H4': 24.784573042734792, 'HCN': 14.147661131269615, 'C2H2': 17.987660911754574, 'CH2_s3B1d': 8.4367502225645694, 'CH3Cl': 17.345703232453161, 'BeH': 2.4056192789431634, 'CO2': 18.042908133550554, 'CH3SH': 20.745692467404297, 'OH': 4.7689596779973726, 'N2H4': 19.655465600395473, 'H2O': 10.164791282175884, 'SO': 6.126486718401793, 'CH2_s1A1d': 7.7608520741205211, 'H2CO': 16.736077719720015, 'HCl': 4.6204106981385848}} En10 = [ref['ea'][name] for name in molecule_names] Dn10 = [ref['distance'][name] for name in molecule_names] print(abs(En1 - En10).max()) print(abs(Dn1 - Dn10).max())
def update(self, atoms=None): if not self.calculation_required(atoms, ['energy', 'forces']): return if atoms is None: atoms = self.calculator.get_atoms() self.energy = self.calculator.get_potential_energy(atoms) self.forces = self.calculator.get_forces(atoms) self.atoms = atoms.copy() if self.vdwradii is not None: # external vdW radii vdwradii = self.vdwradii assert (len(atoms) == len(vdwradii)) else: vdwradii = [] for atom in atoms: self.vdwradii.append(vdWDB_Grimme06jcc[atom.symbol][1]) if self.hirshfeld == None: volume_ratios = [1.] * len(atoms) elif hasattr(self.hirshfeld, '__len__'): # a list assert (len(atoms) == len(self.hirshfeld)) volume_ratios = self.hirshfeld else: # should be an object self.hirshfeld.initialize() volume_ratios = self.hirshfeld.get_effective_volume_ratios() # correction for effective C6 na = len(atoms) C6eff_a = np.empty((na)) alpha_a = np.empty((na)) R0eff_a = np.empty((na)) for a, atom in enumerate(atoms): # free atom values alpha_a[a], C6eff_a[a] = self.vdWDB_alphaC6[atom.symbol] # correction for effective C6 C6eff_a[a] *= Hartree * volume_ratios[a]**2 * Bohr**6 R0eff_a[a] = vdwradii[a] * volume_ratios[a]**(1. / 3.) C6eff_aa = np.empty((na, na)) for a in range(na): for b in range(a, na): C6eff_aa[a, b] = (2 * C6eff_a[a] * C6eff_a[b] / (alpha_a[b] / alpha_a[a] * C6eff_a[a] + alpha_a[a] / alpha_a[b] * C6eff_a[b])) C6eff_aa[b, a] = C6eff_aa[a, b] # PBC pbc_c = atoms.get_pbc() cell_c = atoms.get_cell() Rcell_c = np.sqrt(np.sum(cell_c**2, axis=1)) ncells_c = np.ceil(np.where(pbc_c, 1. + self.Rmax / Rcell_c, 1)) ncells_c = np.array(ncells_c, dtype=int) positions = atoms.get_positions() EvdW = 0.0 forces = 0. * self.forces # loop over all atoms in the cell for ia, posa in enumerate(positions): # loop over all atoms in the cell (and neighbour cells for PBC) for ib, posb in enumerate(positions): # loops over neighbour cells for ix in range(-ncells_c[0] + 1, ncells_c[0]): for iy in range(-ncells_c[1] + 1, ncells_c[1]): for iz in range(-ncells_c[2] + 1, ncells_c[2]): i_c = np.array([ix, iy, iz]) diff = posb + np.dot(i_c, cell_c) - posa r2 = np.dot(diff, diff) r6 = r2**3 r = np.sqrt(r2) if r > 1.e-10 and r < self.Rmax: Edamp, Fdamp = self.damping(r, R0eff_a[ia], R0eff_a[ib], d=self.d, sR=self.sR) EvdW -= (Edamp * C6eff_aa[ia, ib] / r6) # we neglect the C6eff contribution to the # forces forces[ia] -= ((Fdamp - 6 * Edamp / r) * C6eff_aa[ia, ib] / r6 * diff / r) self.energy += EvdW / 2. # double counting self.forces += forces / 2. # double counting if self.txt: prnt(('\n' + self.__class__.__name__), file=self.txt) prnt('vdW correction: %g' % (EvdW / 2.), file=self.txt) prnt('Energy: %g' % self.energy, file=self.txt) prnt('\nForces in eV/Ang:', file=self.txt) c = Hartree / Bohr symbols = self.atoms.get_chemical_symbols() for ia, symbol in enumerate(symbols): prnt('%3d %-2s %10.5f %10.5f %10.5f' % ((ia, symbol) + tuple(self.forces[ia])), file=self.txt)
def __init__(self, calc, xc=None, kpts=None, bands=None, ecut=None, omega=None, world=mpi.world, txt=sys.stdout, timer=None): PairDensity.__init__(self, calc, ecut, world=world, txt=txt, timer=timer) if xc is None or xc == 'EXX': self.exx_fraction = 1.0 xc = XC(XCNull()) elif xc == 'PBE0': self.exx_fraction = 0.25 xc = XC('HYB_GGA_XC_PBEH') elif xc == 'HSE03': omega = 0.106 self.exx_fraction = 0.25 xc = XC('HYB_GGA_XC_HSE03') elif xc == 'HSE06': omega = 0.11 self.exx_fraction = 0.25 xc = XC('HYB_GGA_XC_HSE06') elif xc == 'B3LYP': self.exx_fraction = 0.2 xc = XC('HYB_GGA_XC_B3LYP') self.xc = xc self.omega = omega self.exc = np.nan # density dependent part of xc-energy self.kpts = select_kpts(kpts, self.calc) if bands is None: # Do all occupied bands: bands = [0, self.nocc2] prnt('Calculating exact exchange contributions for band index', '%d-%d' % (bands[0], bands[1] - 1), file=self.fd) prnt('for IBZ k-points with indices:', ', '.join(str(i) for i in self.kpts), file=self.fd) self.bands = bands if self.ecut is None: self.ecut = self.calc.wfs.pd.ecut prnt('Plane-wave cutoff: %.3f eV' % (self.ecut * Hartree), file=self.fd) shape = (self.calc.wfs.nspins, len(self.kpts), bands[1] - bands[0]) self.exxvv_sin = np.zeros(shape) # valence-valence exchange energies self.exxvc_sin = np.zeros(shape) # valence-core exchange energies self.f_sin = np.empty(shape) # occupation numbers # The total EXX energy will not be calculated if we are only # interested in a few eigenvalues for a few k-points self.exx = np.nan # total EXX energy self.exxvv = np.nan # valence-valence self.exxvc = np.nan # valence-core self.exxcc = 0.0 # core-core self.mysKn1n2 = None # my (s, K, n1, n2) indices self.distribute_k_points_and_bands(0, self.nocc2) # All occupied states: self.mykpts = [self.get_k_point(s, K, n1, n2) for s, K, n1, n2 in self.mysKn1n2] prnt('Using Wigner-Seitz truncated coulomb interaction.', file=self.fd) self.wstc = WignerSeitzTruncatedCoulomb(self.calc.wfs.gd.cell_cv, self.calc.wfs.kd.N_c, self.fd) self.iG_qG = {} # cache # PAW matrices: self.V_asii = [] # valence-valence correction self.C_aii = [] # valence-core correction self.initialize_paw_exx_corrections()
def __init__(self, calc, xc=None, kpts=None, bands=None, ecut=150.0, alpha=0.0, skip_gamma=False, world=mpi.world, txt=sys.stdout): alpha /= Bohr**2 PairDensity.__init__(self, calc, ecut, world=world, txt=txt) ecut /= Hartree if xc is None: self.exx_fraction = 1.0 xc = XC(XCNull()) if xc == 'PBE0': self.exx_fraction = 0.25 xc = XC('HYB_GGA_XC_PBEH') elif xc == 'B3LYP': self.exx_fraction = 0.2 xc = XC('HYB_GGA_XC_B3LYP') self.xc = xc self.exc = np.nan # density dependent part of xc-energy if kpts is None: # Do all k-points in the IBZ: kpts = range(self.calc.wfs.kd.nibzkpts) if bands is None: # Do all occupied bands: bands = [0, self.nocc2] prnt('Calculating exact exchange contributions for band index', '%d-%d' % (bands[0], bands[1] - 1), file=self.fd) prnt('for IBZ k-points with indices:', ', '.join(str(i) for i in kpts), file=self.fd) self.kpts = kpts self.bands = bands shape = (self.calc.wfs.nspins, len(kpts), bands[1] - bands[0]) self.exxvv_sin = np.zeros(shape) # valence-valence exchange energies self.exxvc_sin = np.zeros(shape) # valence-core exchange energies self.f_sin = np.empty(shape) # occupation numbers # The total EXX energy will not be calculated if we are only # interested in a few eigenvalues for a few k-points self.exx = np.nan # total EXX energy self.exxvv = np.nan # valence-valence self.exxvc = np.nan # valence-core self.exxcc = 0.0 # core-core self.mysKn1n2 = None # my (s, K, n1, n2) indices self.distribute_k_points_and_bands(self.nocc2) # All occupied states: self.mykpts = [self.get_k_point(s, K, n1, n2) for s, K, n1, n2 in self.mysKn1n2] # Compensation charge used for molecular calculations only: self.beta = None # e^(-beta*r^2) self.ngauss_G = None # density self.vgauss_G = None # potential self.G0 = None # effective value for |G+q| when |G+q|=0 self.skip_gamma = skip_gamma if not self.calc.atoms.pbc.any(): # Set exponent of exp-function to -19 on the boundary: self.beta = 4 * 19 * (self.calc.wfs.gd.icell_cv**2).sum(1).max() prnt('Gaussian for electrostatic decoupling: e^(-beta*r^2),', 'beta=%.3f 1/Ang^2' % (self.beta / Bohr**2), file=self.fd) elif skip_gamma: prnt('Skip |G+q|=0 term', file=self.fd) else: # Volume per q-point: dvq = (2 * pi)**3 / self.vol / self.calc.wfs.kd.nbzkpts qcut = (dvq / (4 * pi / 3))**(1 / 3) if alpha == 0.0: self.G0 = (4 * pi * qcut / dvq)**-0.5 else: self.G0 = (2 * pi**1.5 * erf(alpha**0.5 * qcut) / alpha**0.5 / dvq)**-0.5 prnt('G+q=0 term: Integrate e^(-alpha*q^2)/q^2 for', 'q<%.3f 1/Ang and alpha=%.3f Ang^2' % (qcut / Bohr, alpha * Bohr**2), file=self.fd) # PAW matrices: self.V_asii = [] # valence-valence correction self.C_aii = [] # valence-core correction self.initialize_paw_exx_corrections()
def to_file(self, calculator, filename='multipole.dat', mode='a'): """Expand the charge distribution in multipoles and write the result to a file""" if self.gd is None: self.initialize(calculator.density.finegd) q_L = self.expand(-calculator.density.rhot_g) f = paropen(filename, mode) prnt('# Multipole expansion of the charge density', file=f) prnt('# center =', self.center * Bohr, 'Angstrom', file=f) prnt('# lmax =', self.lmax, file=f) prnt(('# see https://trac.fysik.dtu.dk/projects/gpaw/browser/' + 'trunk/c/bmgs/sharmonic.py'), file=f) prnt('# for the definition of spherical harmonics', file=f) prnt('# l m q_lm[|e| Angstrom**l]', file=f) L = 0 for l in range(self.lmax + 1): for m in range(-l, l + 1): prnt('{0:2d} {1:3d} {2:g}'.format(l, m, q_L[L]), file=f) L += 1 f.close()
def calculate(self, ecut, nbands=None): """Calculate RPA correlation energy for one or several cutoffs. ecut: float or list of floats Plane-wave cutoff(s). nbands: int Number of bands (defaults to number of plane-waves). """ if isinstance(ecut, (float, int)): ecut_i = [ecut] for i in range(5): ecut_i.append(ecut_i[-1] * 0.8) ecut_i = np.sort(ecut_i) else: ecut_i = np.sort(ecut) self.ecut_i = np.asarray(ecut_i) / Hartree ecutmax = max(self.ecut_i) if nbands is None: prnt('Response function bands : Equal to number of plane waves', file=self.fd) else: prnt('Response function bands : %s' % nbands, file=self.fd) prnt('Plane wave cutoff energies :', file=self.fd) for ecut in ecut_i: prnt(' %.0f eV' % ecut, file=self.fd) prnt(file=self.fd) if self.filename and os.path.isfile(self.filename): self.read() self.world.barrier() chi0 = Chi0(self.calc, 1j * Hartree * self.myomega_w, eta=0.0, txt='response.txt', world=self.chicomm) nq = len(self.energy_qi) for q_c in self.ibzq_qc[nq:]: if (q_c == 0.0).all() and self.skip_gamma: self.energy_qi.append(len(self.ecut_i) * [0.0]) self.write() prnt('Not calculating E_c(q) at Gamma', file=self.fd) prnt(file=self.fd) continue thisqd = KPointDescriptor([q_c]) pd = PWDescriptor(ecutmax, self.calc.wfs.gd, complex, thisqd) nG = pd.ngmax chi0_wGG = np.zeros((self.mynw, nG, nG), complex) if not q_c.any(): # Wings (x=0,1) and head (G=0) for optical limit and three # directions (v=0,1,2): chi0_wxvG = np.zeros((self.mynw, 2, 3, nG), complex) else: chi0_wxvG = None Q_aGii = chi0.initialize_paw_corrections(pd) # First not completely filled band: m1 = chi0.nocc1 prnt('# %s - %s' % (len(self.energy_qi), ctime().split()[-2]), file=self.fd) prnt('q = [%1.3f %1.3f %1.3f]' % tuple(q_c), file=self.fd) energy_i = [] for ecut in self.ecut_i: if ecut == ecutmax: # Nothing to cut away: cut_G = None m2 = nbands or nG else: cut_G = np.arange(nG)[pd.G2_qG[0] <= 2 * ecut] m2 = len(cut_G) prnt('E_cut = %d eV / Bands = %d: ' % (ecut * Hartree, m2), file=self.fd, end='', flush=True) energy = self.calculate_q(chi0, pd, chi0_wGG, chi0_wxvG, Q_aGii, m1, m2, cut_G) energy_i.append(energy) m1 = m2 if ecut < ecutmax and self.chicomm.size > 1: # Chi0 will be summed again over chicomm, so we divide # by its size: chi0_wGG *= 1.0 / self.chicomm.size if chi0_wxvG is not None: chi0_wxvG *= 1.0 / self.chicomm.size self.energy_qi.append(energy_i) self.write() prnt(file=self.fd) e_i = np.dot(self.weight_q, np.array(self.energy_qi)) prnt('==========================================================', file=self.fd) prnt(file=self.fd) prnt('Total correlation energy:', file=self.fd) for e_cut, e in zip(self.ecut_i, e_i): prnt('%6.0f: %6.4f eV' % (e_cut * Hartree, e * Hartree), file=self.fd) prnt(file=self.fd) if len(e_i) > 1: self.extrapolate(e_i) prnt('Calculation completed at: ', ctime(), file=self.fd) prnt(file=self.fd) return e_i * Hartree
def calculate_rkernel(self): gd = self.gd ng_c = gd.N_c cell_cv = gd.cell_cv icell_cv = 2 * np.pi * np.linalg.inv(cell_cv) vol = np.linalg.det(cell_cv) ns = self.calc.wfs.nspins n_g = self.n_g # density on rough grid fx_g = ns * self.get_fxc_g(n_g) # local exchange kernel qc_g = (-4 * np.pi * ns / fx_g)**0.5 # cutoff functional flocal_g = qc_g**3 * fx_g / (6 * np.pi**2) # ren. x-kernel for r=r' Vlocal_g = 2 * qc_g / np.pi # ren. Hartree kernel for r=r' ng = np.prod(ng_c) # number of grid points r_vg = gd.get_grid_point_coordinates() rx_g = r_vg[0].flatten() ry_g = r_vg[1].flatten() rz_g = r_vg[2].flatten() prnt(' %d grid points and %d plane waves at the Gamma point' % (ng, self.pd.ngmax), file=self.fd) # Unit cells R_Rv = [] weight_R = [] nR_v = self.unit_cells nR = np.prod(nR_v) for i in range(-nR_v[0] + 1, nR_v[0]): for j in range(-nR_v[1] + 1, nR_v[1]): for h in range(-nR_v[2] + 1, nR_v[2]): R_Rv.append(i * cell_cv[0] + j * cell_cv[1] + h * cell_cv[2]) weight_R.append((nR_v[0] - abs(i)) * (nR_v[1] - abs(j)) * (nR_v[2] - abs(h)) / float(nR)) if nR > 1: # with more than one unit cell only the exchange kernel is # calculated on the grid. The bare Coulomb kernel is added # in PW basis and Vlocal_g only the exchange part dv = self.calc.density.gd.dv gc = (3 * dv / 4 / np.pi)**(1 / 3.) Vlocal_g -= 2 * np.pi * gc**2 / dv prnt(' Lattice point sampling: ' + '(%s x %s x %s)^2 ' % (nR_v[0], nR_v[1], nR_v[2]) + ' Reduced to %s lattice points' % len(R_Rv), file=self.fd) l_g_size = -(-ng // mpi.world.size) l_g_range = range(mpi.world.rank * l_g_size, min((mpi.world.rank+1) * l_g_size, ng)) fhxc_qsGr = {} for iq in range(len(self.ibzq_qc)): fhxc_qsGr[iq] = np.zeros((ns, len(self.pd.G2_qG[iq]), len(l_g_range)), dtype=complex) inv_error = np.seterr() np.seterr(invalid='ignore') np.seterr(divide='ignore') t0 = time() # Loop over Lattice points for i, R_v in enumerate(R_Rv): # Loop over r'. f_rr and V_rr are functions of r (dim. as r_vg[0]) if i == 1: prnt(' Finished 1 cell in %s seconds' % int(time() - t0) + ' - estimated %s seconds left' % int((len(R_Rv) - 1) * (time() - t0)), file=self.fd) self.fd.flush() if len(R_Rv) > 5: if (i+1) % (len(R_Rv) / 5 + 1) == 0: prnt(' Finished %s cells in %s seconds' % (i, int(time() - t0)) + ' - estimated %s seconds left' % int((len(R_Rv) - i) * (time() - t0) / i), file=self.fd) self.fd.flush() for g in l_g_range: rx = rx_g[g] + R_v[0] ry = ry_g[g] + R_v[1] rz = rz_g[g] + R_v[2] # |r-r'-R_i| rr = ((r_vg[0] - rx)**2 + (r_vg[1] - ry)**2 + (r_vg[2] - rz)**2)**0.5 n_av = (n_g + n_g.flatten()[g]) / 2. fx_g = ns * self.get_fxc_g(n_av, index=g) qc_g = (-4 * np.pi * ns / fx_g)**0.5 x = qc_g * rr osc_x = np.sin(x) - x*np.cos(x) f_rr = fx_g * osc_x / (2 * np.pi**2 * rr**3) if nR > 1: # include only exchange part of the kernel here V_rr = (sici(x)[0] * 2 / np.pi - 1) / rr else: # include the full kernel (also hartree part) V_rr = (sici(x)[0] * 2 / np.pi) / rr # Terms with r = r' if (np.abs(R_v) < 0.001).all(): tmp_flat = f_rr.flatten() tmp_flat[g] = flocal_g.flatten()[g] f_rr = tmp_flat.reshape(ng_c) tmp_flat = V_rr.flatten() tmp_flat[g] = Vlocal_g.flatten()[g] V_rr = tmp_flat.reshape(ng_c) del tmp_flat f_rr[np.where(n_av < self.density_cut)] = 0.0 V_rr[np.where(n_av < self.density_cut)] = 0.0 f_rr *= weight_R[i] V_rr *= weight_R[i] # r-r'-R_i r_r = np.array([r_vg[0] - rx, r_vg[1] - ry, r_vg[2] - rz]) # Fourier transform of r for iq, q in enumerate(self.ibzq_qc): q_v = np.dot(q, icell_cv) e_q = np.exp(-1j * gemmdot(q_v, r_r, beta=0.0)) f_q = self.pd.fft((f_rr + V_rr) * e_q, iq) * vol / ng fhxc_qsGr[iq][0, :, g - l_g_range[0]] += f_q if ns == 2: f_q = self.pd.fft(V_rr * e_q, iq) * vol / ng fhxc_qsGr[iq][1, :, g - l_g_range[0]] += f_q mpi.world.barrier() np.seterr(**inv_error) for iq, q in enumerate(self.ibzq_qc): npw = len(self.pd.G2_qG[iq]) fhxc_sGsG = np.zeros((ns * npw, ns * npw), complex) l_pw_size = -(-npw // mpi.world.size) # parallelize over PW below l_pw_range = range(mpi.world.rank * l_pw_size, min((mpi.world.rank + 1) * l_pw_size, npw)) if mpi.world.size > 1: # redistribute grid and plane waves in fhxc_qsGr[iq] bg1 = BlacsGrid(mpi.world, 1, mpi.world.size) bg2 = BlacsGrid(mpi.world, mpi.world.size, 1) bd1 = bg1.new_descriptor(npw, ng, npw, - (-ng / mpi.world.size)) bd2 = bg2.new_descriptor(npw, ng, -(-npw / mpi.world.size), ng) fhxc_Glr = np.zeros((len(l_pw_range), ng), dtype=complex) if ns == 2: Koff_Glr = np.zeros((len(l_pw_range), ng), dtype=complex) r = Redistributor(bg1.comm, bd1, bd2) r.redistribute(fhxc_qsGr[iq][0], fhxc_Glr, npw, ng) if ns == 2: r.redistribute(fhxc_qsGr[iq][1], Koff_Glr, npw, ng) else: fhxc_Glr = fhxc_qsGr[iq][0] if ns == 2: Koff_Glr = fhxc_qsGr[iq][1] # Fourier transform of r' for iG in range(len(l_pw_range)): f_g = fhxc_Glr[iG].reshape(ng_c) f_G = self.pd.fft(f_g.conj(), iq) * vol / ng fhxc_sGsG[l_pw_range[0] + iG, :npw] = f_G.conj() if ns == 2: v_g = Koff_Glr[iG].reshape(ng_c) v_G = self.pd.fft(v_g.conj(), iq) * vol / ng fhxc_sGsG[npw + l_pw_range[0] + iG, :npw] = v_G.conj() if ns == 2: # f_00 = f_11 and f_01 = f_10 fhxc_sGsG[:npw, npw:] = fhxc_sGsG[npw:, :npw] fhxc_sGsG[npw:, npw:] = fhxc_sGsG[:npw, :npw] mpi.world.sum(fhxc_sGsG) fhxc_sGsG /= vol if mpi.rank == 0: w = Writer('fhxc_%s_%s_%s_%s.gpw' % (self.tag, self.xc, self.ecut, iq)) w.dimension('sG', ns * npw) w.add('fhxc_sGsG', ('sG', 'sG'), dtype=complex) if nR > 1: # add Hartree kernel evaluated in PW basis Gq2_G = self.pd.G2_qG[iq] if (q == 0).all(): Gq2_G[0] = 1. vq_G = 4 * np.pi / Gq2_G fhxc_sGsG += np.tile(np.eye(npw) * vq_G, (ns, ns)) w.fill(fhxc_sGsG) w.close() mpi.world.barrier() prnt(file=self.fd)
ve.append((abs(np.linalg.det(d.cell)), d.energy)) except AttributeError: ve.append((np.nan, np.nan)) # sort according to volume ves = sorted(ve, key=lambda x: x[0]) # EOS eos = EquationOfState([t[0] for t in ves], [t[1] for t in ves]) try: v, e, B0, B1, R = eos.fit() except (ValueError, TypeError, LinAlgError): (v, e, B0, B1, R) = (np.nan, np.nan, np.nan, np.nan, np.nan) e = e / len(collection[name]) v = v / len(collection[name]) B0 = B0 / kJ * 1.0e24 # GPa A.append((e, v, B0, B1, R)) return np.array(A).T E, V, B0, B1, R = analyse(c, collection) fd = open(db + '_raw.txt', 'w') for name, e, v, b0, b1, r, in zip(collection.names, E, V, B0, B1, R): if not np.isnan(e): prnt('%2s %8.4f %8.4f %8.4f' % (name, v, b0, b1), file=fd) fd = open(db + '_raw.csv', 'w') for name, e, v, b0, b1, r, in zip(collection.names, E, V, B0, B1, R): if not np.isnan(e): prnt('%s, %8.4f, %8.4f, %8.4f' % (name, v, b0, b1), file=fd)
if len(sys.argv) == 2 and 'run.py' not in sys.argv: db = sys.argv[1] else: db = 'compression.db' # default db file c = ase.db.connect(db) def analyse(c, names, linspace): A = [] for name in names: e = [] # energies for x in linspace: try: d = c.get(name=name, x=x) assert name == d.name e.append(d.energy) except (KeyError, AttributeError): e.append(np.nan) while len(e) < len(linspace): # missing data e.append(np.nan) A.append(e) return A E = analyse(c, names, linspace) fd = open(db + '_energies.csv', 'w') prnt('c' + ',' + ','.join([str(round(e, 3)) for e in linspace]), file=fd) for name, energies, in zip(names, E): prnt(name + ',' + ','.join([str(round(e, 4)) for e in energies]), file=fd)
ve.append((np.nan, np.nan)) # sort according to volume ves = sorted(ve, key=lambda x: x[0]) # EOS eos = EquationOfState([t[0] for t in ves], [t[1] for t in ves]) try: v, e0, B0, B1, R = eos.fit() except (ValueError, TypeError, LinAlgError): (v, e0, B0, B1, R) = (np.nan, np.nan, np.nan, np.nan, [np.nan]) if not R: R = [np.nan] # sometimes R is an empty array if not isinstance(R, list): R = [R] # sometimes R is not a list e0 = e0 v = v B0 = B0 / kJ * 1.0e24 # GPa A.append((e0, v, B0, B1, R[0])) return np.array(A).T E0, V, B0, B1, R = analyse(c, names) fd = open(db + '_raw.txt', 'w') for name, e0, v, b0, b1, r, in zip(names, E0, V, B0, B1, R): if not np.isnan(e0): prnt('%2s %8.4f %8.4f %8.4f %8.4f' % (name, e0, v, b0, b1), file=fd) fd = open(db + '_raw.csv', 'w') for name, e0, v, b0, b1, r, in zip(names, E0, V, B0, B1, R): if not np.isnan(e0): prnt('%s, %8.4f, %8.4f, %8.4f, %8.4f' % (name, e0, v, b0, b1), file=fd)
def print_initialization(self, xc, frequency_scale, nlambda): prnt('----------------------------------------------------------', file=self.fd) prnt('Non-self-consistent %s correlation energy' % xc, file=self.fd) prnt('----------------------------------------------------------', file=self.fd) prnt('Started at: ', ctime(), file=self.fd) prnt(file=self.fd) prnt('Atoms :', self.calc.atoms.get_chemical_formula(mode='hill'), file=self.fd) prnt('Ground state XC functional :', self.calc.hamiltonian.xc.name, file=self.fd) prnt('Valence electrons :', self.calc.wfs.setups.nvalence, file=self.fd) prnt('Number of bands :', self.calc.wfs.bd.nbands, file=self.fd) prnt('Number of spins :', self.calc.wfs.nspins, file=self.fd) prnt('Number of k-points :', len(self.calc.wfs.kd.bzk_kc), file=self.fd) prnt('Number of irreducible k-points :', len(self.calc.wfs.kd.ibzk_kc), file=self.fd) prnt('Number of q-points :', len(self.bzq_qc), file=self.fd) prnt('Number of irreducible q-points :', len(self.ibzq_qc), file=self.fd) prnt(file=self.fd) for q, weight in zip(self.ibzq_qc, self.weight_q): prnt(' q: [%1.4f %1.4f %1.4f] - weight: %1.3f' % (q[0], q[1], q[2], weight), file=self.fd) prnt(file=self.fd) prnt('----------------------------------------------------------', file=self.fd) prnt('----------------------------------------------------------', file=self.fd) prnt(file=self.fd) if nlambda is None: prnt('Analytical coupling constant integration', file=self.fd) else: prnt('Numerical coupling constant integration using', nlambda, 'Gauss-Legendre points', file=self.fd) prnt(file=self.fd) prnt('Frequencies', file=self.fd) prnt(' Gauss-Legendre integration with %s frequency points' % len(self.omega_w), file=self.fd) prnt(' Transformed from [0,\infty] to [0,1] using e^[-aw^(1/B)]', file=self.fd) prnt(' Highest frequency point at %5.1f eV and B=%1.1f' % (self.omega_w[-1] * Hartree, frequency_scale), file=self.fd) prnt(file=self.fd) prnt('Parallelization', file=self.fd) prnt(' Total number of CPUs : % s' % self.world.size, file=self.fd) prnt(' Frequency decomposition : % s' % self.wcomm.size, file=self.fd) prnt(' K-point/band decomposition : % s' % self.chicomm.size, file=self.fd) prnt(file=self.fd)
siter = siter + c.get(name=name, category='fcc111', adsorbate='').niter stime = stime + c.get(name=name, category='fcc111', adsorbate='').time N = N + 1 siter = siter + c.get(name=name, category='fcc111', adsorbate='O').niter stime = stime + c.get(name=name, category='fcc111', adsorbate='O').time N = N + 1 siter = siter + c.get(name=name, category='fcc111', adsorbate='C').niter stime = stime + c.get(name=name, category='fcc111', adsorbate='C').time N = N + 1 siter = siter + c.get(name='O', category='fcc', adsorbate='').niter stime = stime + c.get(name='O', category='fcc', adsorbate='').time N = N + 1 siter = siter + c.get(name='C', category='fcc', adsorbate='').niter stime = stime + c.get(name='C', category='fcc', adsorbate='').time N = N + 1 results[7] = siter / N results[8] = stime / N except: pass A.append(results) return np.array(A) results = analyse(c, names) fd = open(db + '_raw.txt', 'w') for name, r in zip(names, results): prnt('%2s %s' % (name, str(' '.join([str(round(r0, 4)) for r0 in r]))), file=fd) fd = open(db + '_raw.csv', 'w') for name, r in zip(names, results): prnt('%2s,%s' % (name, str(','.join([str(round(r0, 4)) for r0 in r]))), file=fd)