def gen_test_data(datadir: str, params_fd: dict, supercell): from gpaw.elph.electronphonon import ElectronPhononCoupling params_gs = copy.deepcopy(params_fd) atoms = Cluster(ase.build.bulk('C')) calc_gs = GPAW(**params_gs) atoms.calc = calc_gs atoms.get_potential_energy() atoms.calc.write("gs.gpw", mode="all") # Make sure the real space grid matches the original. # (basically we multiply the number of grid points in each dimension by the supercell dimension) params_fd['gpts'] = calc_gs.wfs.gd.N_c * list(supercell) if 'h' in params_fd: del params_fd['h'] del calc_gs if world.rank == 0: os.makedirs(datadir, exist_ok=True) calc_fd = GPAW(**params_fd) elph = ElectronPhononCoupling(atoms, calc=calc_fd, supercell=supercell, calculate_forces=True, name=f'{datadir}/elph') elph.run() calc_fd.wfs.gd.comm.barrier() elph = ElectronPhononCoupling(atoms, calc=calc_fd, supercell=supercell) elph.set_lcao_calculator(calc_fd) elph.calculate_supercell_matrix(dump=1)
from ase.build import molecule from ase import optimize from ase.vibrations.infrared import InfraRed from gpaw.cluster import Cluster from gpaw import GPAW, FermiDirac h = 0.22 atoms = Cluster(molecule('H2')) atoms.minimal_box(3.5, h=h) # relax the molecule calc = GPAW(h=h, occupations=FermiDirac(width=0.1)) atoms.calc = calc dyn = optimize.FIRE(atoms) dyn.run(fmax=0.05) atoms.write('relaxed.traj') # finite displacement for vibrations ir = InfraRed(atoms) ir.run()
def main__raman_ch4(structure, supercell, log): import ase.build from gpaw.lrtddft.spectrum import polarizability from gpaw.cluster import Cluster from gpaw import GPAW, FermiDirac #============================================= # Settings # Input structure relax_grid_sep = 0.22 # GPAW finite grid size vacuum_sep = 3.5 pbc = False if structure == 'ch4': def get_unrelaxed_structure(): atoms = Cluster(ase.build.molecule('CH4')) atoms.minimal_box(vacuum_sep, h=relax_grid_sep) return atoms elif structure == 'mos2': def get_unrelaxed_structure(): atoms = Cluster(ase.build.mx2('MoS2')) atoms.center(vacuum=vacuum_sep, axis=2) return atoms # Calculator (general settings) make_calc = functools.partial(GPAW, occupations=FermiDirac(width=0.1), symmetry={'point_group': False}, txt=log, ) # Relaxation settings make_calc_relax = functools.partial(make_calc, h=relax_grid_sep, ) # Args for computations on displaced structures raman_grid_sep = 0.25 # In the example, they use a larger spacing here than during relaxation. # (TODO: but why? On CH4 I observe that this to leads to equilibrium forces of # 0.067 ev/A, which seems to compromise our "energy minimum" state...) num_converged_bands = 10 num_total_bands = 20 make_calc_raman = functools.partial(make_calc, h=raman_grid_sep, convergence={ 'eigenstates': 1.e-5, 'bands': num_converged_bands, }, eigensolver='cg', nbands=num_total_bands, ) supercell_matrix = [[supercell[0], 0, 0], [0, supercell[1], 0], [0, 0, supercell[2]]] displacement_distance = 1e-2 # ---------- # Excitation settings (for polarizability) ex_kw = {'restrict': {'jend':num_converged_bands-1}} omega = 5.0 # eV get_polarizability = functools.partial(polarizability, omega=omega, form='v', tensor=True) subtract_equilibrium_polarizability = False #============================================= # Process disp_filenames = { 'ex': {'eq': 'raman-eq.ex.gz', 'disp': 'raman-{:04}.ex.gz'}, 'force': {'eq': 'force-set-eq.npy', 'disp': 'force-set-{:04}.npy'}, } # Relax unrelaxed_atoms = get_unrelaxed_structure() unrelaxed_atoms.pbc = pbc unrelaxed_atoms.calc = make_calc_relax() relax_atoms(outpath='relaxed.vasp', atoms=unrelaxed_atoms) # Phonopy displacements phonon = get_minimum_displacements(cachepath='phonopy_disp.yaml', unitcell=phonopy.interface.calculator.read_crystal_structure('relaxed.vasp', interface_mode='vasp')[0], supercell_matrix=supercell_matrix, displacement_distance=displacement_distance, ) # Computing stuff at displacements eq_atoms = Cluster(phonopy_atoms_to_ase(phonon.supercell)) eq_atoms.pbc = pbc if raman_grid_sep != relax_grid_sep: eq_atoms.minimal_box(vacuum_sep, h=raman_grid_sep) eq_atoms.calc = make_calc_raman() force_sets = make_force_sets_and_excitations(cachepath='force-sets.npy', disp_filenames=disp_filenames, phonon=phonon, atoms=eq_atoms, ex_kw=ex_kw, ) phonon.set_forces(force_sets) # Applying symmetry cart_pol_derivs = expand_raman_by_symmetry(cachepath='raman-cart.npy', phonon=phonon, disp_filenames=disp_filenames, get_polarizability=get_polarizability, ex_kw=ex_kw, subtract_equilibrium_polarizability=subtract_equilibrium_polarizability, ) # Phonopy part 2 gamma_eigendata = get_eigensolutions_at_q(cachepath='eigensolutions-gamma.npz', phonon=phonon, q=[0, 0, 0], ) # Raman of modes get_mode_raman(outpath='mode-raman-gamma.npy', eigendata=gamma_eigendata, cart_pol_derivs=cart_pol_derivs, )
epsinf = 78.36 rhomin = 0.0001 / Bohr**3 rhomax = 0.0050 / Bohr**3 st = 50. * 1e-3 * Pascal * m p = -0.35 * 1e9 * Pascal convergence = { 'energy': 0.05 / 8., 'density': 10., 'eigenstates': 10., } atoms = Cluster(molecule('H2O')) atoms.minimal_box(vac, h) if not SKIP_VAC_CALC: atoms.calc = GPAW(xc='PBE', h=h, convergence=convergence) Evac = atoms.get_potential_energy() print(Evac) else: # h=0.24, vac=4.0, setups: 0.9.11271, convergence: only energy 0.05 / 8 Evac = -14.857414548 with warnings.catch_warnings(): # ignore production code warning for ADM12PoissonSolver warnings.simplefilter("ignore") psolver = ADM12PoissonSolver() atoms.calc = SolvationGPAW(xc='PBE', h=h, poissonsolver=psolver, convergence=convergence,
epsinf = 78.36 rho0 = 0.00078 / Bohr**3 beta = 1.3 st = 72. * 1e-3 * Pascal * m convergence = { 'energy': 0.05 / 8., 'density': 10., 'eigenstates': 10., } atoms = Cluster(Atoms('Cl')) atoms.minimal_box(vac, h) if not SKIP_VAC_CALC: atoms.calc = GPAW(xc='PBE', h=h, charge=-1, convergence=convergence) Evac = atoms.get_potential_energy() print(Evac) else: # h=0.24, vac=4.0, setups: 0.9.11271, convergence: only energy 0.05 / 8 Evac = -3.83245253419 atoms.calc = SolvationGPAW( xc='PBE', h=h, charge=-1, convergence=convergence, cavity=FG02SmoothStepCavity(rho0=rho0, beta=beta, density=ElDensity(), surface_calculator=GradientSurface()),
T = 298.15 vdw_radii = vdw_radii.copy() vdw_radii[1] = 1.09 atomic_radii = lambda atoms: [vdw_radii[n] for n in atoms.numbers] convergence = { 'energy': 0.05 / 8., 'density': 10., 'eigenstates': 10., } atoms = Cluster(molecule('H2O')) atoms.minimal_box(vac, h) atoms.pbc = True with warnings.catch_warnings(): # ignore production code warning for ADM12PoissonSolver warnings.simplefilter("ignore") psolver = ADM12PoissonSolver(eps=1e-7) atoms.calc = SolvationGPAW( xc='LDA', h=h, convergence=convergence, cavity=EffectivePotentialCavity( effective_potential=Power12Potential(atomic_radii=atomic_radii, u0=u0), temperature=T ), dielectric=LinearDielectric(epsinf=epsinf), poissonsolver=psolver ) atoms.get_potential_energy() atoms.get_forces()
SKIP_VAC_CALC = True h = 0.24 vac = 4.0 convergence = { 'energy': 0.05 / 8., 'density': 10., 'eigenstates': 10., } atoms = Cluster(molecule('H2O')) atoms.minimal_box(vac, h) if not SKIP_VAC_CALC: atoms.calc = GPAW(xc='PBE', h=h, convergence=convergence) Evac = atoms.get_potential_energy() print(Evac) else: # h=0.24, vac=4.0, setups: 0.9.11271, convergence: only energy 0.05 / 8 Evac = -14.857414548 atoms.calc = SolvationGPAW( xc='PBE', h=h, convergence=convergence, **get_HW14_water_kwargs() ) Ewater = atoms.get_potential_energy() Eelwater = atoms.calc.get_electrostatic_energy() Esurfwater = atoms.calc.get_solvation_interaction_energy('surf') atoms.get_forces() DGSol = (Ewater - Evac) / (kcal / mol)
atoms2 = atoms.copy() atoms2.set_initial_magnetic_moments(None) atomss = (atoms, atoms2) Es = [] Fs = [] for atoms in atomss: atoms.calc = SolvationGPAW( xc='LDA', h=h, charge=-1, cavity=EffectivePotentialCavity(effective_potential=Power12Potential( atomic_radii, u0), temperature=T, surface_calculator=GradientSurface(), volume_calculator=KB51Volume()), dielectric=LinearDielectric(epsinf=epsinf), interactions=[ SurfaceInteraction(surface_tension=100. * 1e-3 * Pascal * m), VolumeInteraction(pressure=-1.0 * 1e9 * Pascal), LeakedDensityInteraction(voltage=1.0) ]) Es.append(atoms.get_potential_energy()) Fs.append(atoms.get_forces()) # compare to expected difference of a gas phase calc print('difference E: ', Es[0] - Es[1]) equal(Es[0], Es[1], 0.0002) print('difference F: ', np.abs(Fs[0] - Fs[1]).max()) equal(Fs[0], Fs[1], 0.003)