def run_task(self, fw_spec): unitcell = read_vasp("POSCAR-unitcell") phonon = phonopy.Phonopy(unitcell, self.get("supercell")) supercell = phonon.get_supercell() phonon.generate_displacements() supercells = phonon.supercells_with_displacements ids = np.arange(len(supercells)) + 1 write_supercells_with_displacements(supercell, supercells, ids) units = get_default_physical_units("vasp") phpy_yaml = PhonopyYaml(physical_units=units, settings={ 'force_sets': False, 'born_effective_charge': False, 'dielectric_constant': False, 'displacements': True }) phpy_yaml.set_phonon_info(phonon) with open("phonopy_disp.yaml", 'w') as w: w.write(str(phpy_yaml))
def write_supercells_with_displacements(interface_mode, supercell, cells_with_disps, num_unitcells_in_supercell, optional_structure_info): if interface_mode is None or interface_mode == 'vasp': from phonopy.interface.vasp import write_supercells_with_displacements write_supercells_with_displacements(supercell, cells_with_disps) elif interface_mode is 'abinit': from phonopy.interface.abinit import ( write_supercells_with_displacements) write_supercells_with_displacements(supercell, cells_with_disps) elif interface_mode is 'qe': from phonopy.interface.qe import write_supercells_with_displacements write_supercells_with_displacements(supercell, cells_with_disps, optional_structure_info[1]) elif interface_mode == 'wien2k': from phonopy.interface.wien2k import ( write_supercells_with_displacements) unitcell_filename, npts, r0s, rmts = optional_structure_info write_supercells_with_displacements(supercell, cells_with_disps, npts, r0s, rmts, num_unitcells_in_supercell, filename=unitcell_filename) elif interface_mode == 'elk': from phonopy.interface.elk import write_supercells_with_displacements write_supercells_with_displacements(supercell, cells_with_disps, optional_structure_info[1]) elif interface_mode == 'siesta': from phonopy.interface.siesta import ( write_supercells_with_displacements) write_supercells_with_displacements(supercell, cells_with_disps, optional_structure_info[1]) elif interface_mode == 'cp2k': from phonopy.interface.cp2k import write_supercells_with_displacements write_supercells_with_displacements(supercell, cells_with_disps) elif interface_mode == 'crystal': from phonopy.interface.crystal import ( write_supercells_with_displacements) write_supercells_with_displacements(supercell, cells_with_disps, optional_structure_info[1], num_unitcells_in_supercell, template_file="TEMPLATE") elif interface_mode == 'dftbp': from phonopy.interface.dftbp import ( write_supercells_with_displacements) write_supercells_with_displacements(supercell, cells_with_disps) elif interface_mode == 'turbomole': from phonopy.interface.turbomole import ( write_supercells_with_displacements) write_supercells_with_displacements(supercell, cells_with_disps) else: raise RuntimeError("No calculator interface was found.")
def write_supercells_with_displacements(interface_mode, supercell, cells_with_disps, optional_structure_info, displacement_ids=None, zfill_width=3, additional_info=None): """Utility method to write out supercell structures with displacements interface_mode : str Calculator interface such as 'vasp', 'qe', ... supercell : Supercell Supercell. cells_with_disps : list of PhonopyAtoms Supercells with displacements. optional_structure_info : tuple Information returned by the method ``read_crystal_structure``. See the docstring. displacements_ids : array_like or None, optional Integer 1d array with the length of cells_with_disps, containing numbers to be assigned to the supercells with displacements. Default is None, which gives [1, 2, 3, ...]. zfill_width : int, optional Supercell numbers are filled by zeros from the left with the digits as given, which results in 001, 002, ..., when zfill_width=3. additional_info : dict or None, optional Any information expected to be given to writers of calculators. Default is None. """ if displacement_ids is None: ids = np.arange(len(cells_with_disps), dtype=int) + 1 else: ids = displacement_ids args = (supercell, cells_with_disps, ids) kwargs = {'width': zfill_width} if 'pre_filename' in additional_info: kwargs['pre_filename'] = additional_info['pre_filename'] if interface_mode is None or interface_mode == 'vasp': import phonopy.interface.vasp as vasp vasp.write_supercells_with_displacements(*args, **kwargs) write_magnetic_moments(supercell, sort_by_elements=True) elif interface_mode == 'abinit': import phonopy.interface.abinit as abinit abinit.write_supercells_with_displacements(*args, **kwargs) elif interface_mode == 'qe': import phonopy.interface.qe as qe pp_filenames = optional_structure_info[1] qe_args = args + (pp_filenames, ) qe.write_supercells_with_displacements(*qe_args, **kwargs) write_magnetic_moments(supercell, sort_by_elements=False) elif interface_mode == 'wien2k': import phonopy.interface.wien2k as wien2k unitcell_filename, npts, r0s, rmts = optional_structure_info N = abs(determinant(additional_info['supercell_matrix'])) w2k_args = args + (npts, r0s, rmts, N) if 'pre_filename' not in kwargs: kwargs['pre_filename'] = unitcell_filename wien2k.write_supercells_with_displacements(*w2k_args, **kwargs) elif interface_mode == 'elk': import phonopy.interface.elk as elk sp_filenames = optional_structure_info[1] elk_args = args + (sp_filenames, ) elk.write_supercells_with_displacements(*elk_args, **kwargs) elif interface_mode == 'siesta': import phonopy.interface.siesta as siesta atypes = optional_structure_info[1] sst_args = args + (atypes, ) siesta.write_supercells_with_displacements(*sst_args, **kwargs) elif interface_mode == 'cp2k': import phonopy.interface.cp2k as cp2k cp2k_args = args + (optional_structure_info, ) cp2k.write_supercells_with_displacements(*cp2k_args, **kwargs) elif interface_mode == 'crystal': import phonopy.interface.crystal as crystal if additional_info is None: kwargs['template_file'] = "TEMPLATE" else: kwargs['template_file'] = additional_info.get( 'template_file', "TEMPLATE") conv_numbers = optional_structure_info[1] N = abs(determinant(additional_info['supercell_matrix'])) cst_args = args + (conv_numbers, N) crystal.write_supercells_with_displacements(*cst_args, **kwargs) elif interface_mode == 'dftbp': import phonopy.interface.dftbp as dftbp dftbp.write_supercells_with_displacements(*args, **kwargs) elif interface_mode == 'turbomole': import phonopy.interface.turbomole as turbomole turbomole.write_supercells_with_displacements(*args, **kwargs) elif interface_mode == 'aims': import phonopy.interface.aims as aims aims.write_supercells_with_displacements(*args, **kwargs) else: raise RuntimeError("No calculator interface was found.")
def calculate_phonon(atoms, calc, ndim=np.eye(3), primitive_matrix=np.eye(3), distance=0.01, factor=VaspToTHz, is_symmetry=True, symprec=1e-5, func=None, **func_args): """ """ if 'magmoms' in atoms.arrays: is_mag = True else: is_mag = False # 1. get displacements and supercells atoms.set_calculator(calc) # bulk = PhonopyAtoms(atoms=atoms) if is_mag: bulk = PhonopyAtoms( symbols=atoms.get_chemical_symbols(), scaled_positions=atoms.get_scaled_positions(), cell=atoms.get_cell(), magmoms=atoms.arrays['magmoms'], ) else: bulk = PhonopyAtoms(symbols=atoms.get_chemical_symbols(), scaled_positions=atoms.get_scaled_positions(), cell=atoms.get_cell()) phonon = Phonopy(bulk, ndim, primitive_matrix=primitive_matrix, factor=factor, symprec=symprec) phonon.generate_displacements(distance=distance) disps = phonon.get_displacements() for d in disps: print("[phonopy] %d %s" % (d[0], d[1:])) supercell0 = phonon.get_supercell() supercells = phonon.get_supercells_with_displacements() write_supercells_with_displacements(supercell0, supercells) write_disp_yaml(disps, supercell0) # 2. calculated forces. set_of_forces = [] for iscell, scell in enumerate(supercells): cell = Atoms(symbols=scell.get_chemical_symbols(), scaled_positions=scell.get_scaled_positions(), cell=scell.get_cell(), pbc=True) if is_mag: cell.set_initial_magnetic_moments( atoms.get_initial_magnetic_moments()) cell.set_calculator(calc) dir_name = "PHON_CELL%s" % iscell cur_dir = os.getcwd() if not os.path.exists(dir_name): os.mkdir(dir_name) os.chdir(dir_name) forces = cell.get_forces() #print "[Phonopy] Forces: %s" % forces # Do something other than calculating the forces with func. # func: func(atoms, calc, func_args) if func is not None: func(cell, calc, **func_args) os.chdir(cur_dir) drift_force = forces.sum(axis=0) #print "[Phonopy] Drift force:", "%11.5f" * 3 % tuple(drift_force) # Simple translational invariance for force in forces: force -= drift_force / forces.shape[0] set_of_forces.append(forces) # Phonopy post-process phonon.produce_force_constants(forces=set_of_forces) force_constants = phonon.get_force_constants() write_FORCE_CONSTANTS(force_constants, filename='FORCE_CONSTANTS') print('') print("[Phonopy] Phonon frequencies at Gamma:") for i, freq in enumerate(phonon.get_frequencies((0, 0, 0))): print("[Phonopy] %3d: %10.5f THz" % (i + 1, freq)) # THz print("[Phonopy] %3d: %10.5f cm-1" % (i + 1, freq * 33.35)) #cm-1 return phonon
NNN, # primitive_matrix = [[0.5,0.5,0],[0,0.5,0.5],[0.5,0,0.5]], primitive_matrix=primitive_matrix, nac_params=nac_params, factor=factor, is_symmetry=is_symmetry, ) phonon.generate_displacements( distance=delta, is_plusminus=is_plusminus, ) pho_disp = phonon.get_supercells_with_displacements() vasp.write_supercells_with_displacements( phonon.get_supercell(), pho_disp, ) ######### get new phonon object ########## # import ss_phonopy as ssp phonon = ssp.calc_phonon( calc, phonon, acoustic_sum_rule=acou_sum_rule, rot_sum_rule=rot_sum_rule, r_cut=r_cut, # F_0_correction=True, # verbose=True, # ase_calc=ase_calc, cp_files=cp_files,
def calculate_phonon(atoms, calc=None, forces_set_file=None, ndim=np.eye(3), primitive_matrix=np.eye(3), distance=0.01, factor=VaspToTHz, is_plusminus='auto', is_symmetry=True, symprec=1e-5, func=None, prepare_initial_wavecar=False, skip=None, parallel=True, **func_args): """ """ if 'magmoms' in atoms.arrays or 'initial_magmoms' in atoms.arrays: is_mag = True else: is_mag = False print("is_mag: ", is_mag) # 1. get displacements and supercells if calc is not None: atoms.set_calculator(calc) # bulk = PhonopyAtoms(atoms=atoms) if is_mag: bulk = PhonopyAtoms( symbols=atoms.get_chemical_symbols(), scaled_positions=atoms.get_scaled_positions(), cell=atoms.get_cell(), magmoms=atoms.arrays['initial_magmoms'], ) else: bulk = PhonopyAtoms(symbols=atoms.get_chemical_symbols(), scaled_positions=atoms.get_scaled_positions(), cell=atoms.get_cell()) phonon = Phonopy(bulk, ndim, primitive_matrix=primitive_matrix, factor=factor, symprec=symprec) phonon.generate_displacements(distance=distance, is_plusminus=is_plusminus) disps = phonon.get_displacements() for d in disps: print(("[phonopy] %d %s" % (d[0], d[1:]))) supercell0 = phonon.get_supercell() supercells = phonon.get_supercells_with_displacements() write_supercells_with_displacements(supercell0, supercells) write_disp_yaml(disps, supercell0) # 2. calculated forces. if forces_set_file is not None: symmetry = phonon.get_symmetry() set_of_forces = parse_FORCE_SETS( is_translational_invariance=False, filename=forces_set_file) #['first_atoms'] #set_of_forces=np.array(set_of_forces) #set_of_forces=[np.asarray(f) for f in set_of_forces] phonon.set_displacement_dataset(set_of_forces) phonon.produce_force_constants() else: set_of_forces = [] if prepare_initial_wavecar and skip is None: scell = supercell0 cell = Atoms(symbols=scell.get_chemical_symbols(), scaled_positions=scell.get_scaled_positions(), cell=scell.get_cell(), pbc=True) if is_mag: cell.set_initial_magnetic_moments( atoms.get_initial_magnetic_moments()) mcalc = copy.deepcopy(calc) mcalc.set(lwave=True, lcharg=True) cell.set_calculator(mcalc) dir_name = "SUPERCELL0" cur_dir = os.getcwd() if not os.path.exists(dir_name): os.mkdir(dir_name) os.chdir(dir_name) mcalc.scf_calculation() os.chdir(cur_dir) def calc_force(iscell): scell = supercells[iscell] cell = Atoms(symbols=scell.get_chemical_symbols(), scaled_positions=scell.get_scaled_positions(), cell=scell.get_cell(), pbc=True) if is_mag: cell.set_initial_magnetic_moments( atoms.get_initial_magnetic_moments()) cell.set_calculator(copy.deepcopy(calc)) dir_name = "PHON_CELL%s" % iscell cur_dir = os.getcwd() if not os.path.exists(dir_name): os.mkdir(dir_name) if prepare_initial_wavecar: os.system('ln -s %s %s' % (os.path.abspath("SUPERCELL0/WAVECAR"), os.path.join(dir_name, 'WAVECAR'))) os.chdir(dir_name) forces = cell.get_forces() print("[Phonopy] Forces: %s" % forces) # Do something other than calculating the forces with func. # func: func(atoms, calc, func_args) if func is not None: func(cell, calc, **func_args) os.chdir(cur_dir) drift_force = forces.sum(axis=0) print("[Phonopy] Drift force:", "%11.5f" * 3 % tuple(drift_force)) # Simple translational invariance for force in forces: force -= drift_force / forces.shape[0] return forces #with ProcessPoolExecutor() as executor: # if skip is not None: # skip=0 # set_of_forces=executor.map(calc_force,list(range(skip,len(supercells)))) if skip is None: iskip = 0 else: iskip = skip if parallel: p = Pool() set_of_forces = p.map(calc_force, list(range(iskip, len(supercells)))) else: set_of_forces = [] for iscell, scell in enumerate(supercells[iskip:]): set_of_forces.append(calc_force(iscell)) #phonon.set_displacement_dataset(set_of_forces) phonon.produce_force_constants(forces=np.array(set_of_forces)) # Phonopy post-process print('==============') print(phonon._displacement_dataset['first_atoms']) #phonon.produce_force_constants(forces=np.array(set_of_forces)) #phonon.produce_force_constants() force_constants = phonon.get_force_constants() #print(force_constants) write_FORCE_CONSTANTS(force_constants, filename='FORCE_CONSTANTS') #print("[Phonopy] Phonon frequencies at Gamma:") #for i, freq in enumerate(phonon.get_frequencies((0, 0, 0))): # print(("[Phonopy] %3d: %10.5f THz" % (i + 1, freq))) # THz # print(("[Phonopy] %3d: %10.5f cm-1" % (i + 1, freq * 33.35))) #cm-1 with open('phonon.pickle', 'wb') as myfile: pickle.dump(phonon, myfile) return phonon
def write_supercells_with_displacements(interface_mode, supercell, cells_with_disps, num_unitcells_in_supercell, optional_structure_info): if interface_mode is None or interface_mode == 'vasp': from phonopy.interface.vasp import write_supercells_with_displacements write_supercells_with_displacements(supercell, cells_with_disps) elif interface_mode is 'abinit': from phonopy.interface.abinit import write_supercells_with_displacements write_supercells_with_displacements(supercell, cells_with_disps) elif interface_mode is 'qe': from phonopy.interface.qe import write_supercells_with_displacements write_supercells_with_displacements(supercell, cells_with_disps, optional_structure_info[1]) elif interface_mode == 'wien2k': from phonopy.interface.wien2k import write_supercells_with_displacements unitcell_filename, npts, r0s, rmts = optional_structure_info write_supercells_with_displacements( supercell, cells_with_disps, npts, r0s, rmts, num_unitcells_in_supercell, filename=unitcell_filename) elif interface_mode == 'elk': from phonopy.interface.elk import write_supercells_with_displacements write_supercells_with_displacements(supercell, cells_with_disps, optional_structure_info[1]) elif interface_mode == 'siesta': from phonopy.interface.siesta import write_supercells_with_displacements write_supercells_with_displacements(supercell, cells_with_disps, optional_structure_info[1]) elif interface_mode == 'cp2k': from phonopy.interface.cp2k import write_supercells_with_displacements write_supercells_with_displacements(supercell, cells_with_disps) elif interface_mode == 'crystal': from phonopy.interface.crystal import write_supercells_with_displacements write_supercells_with_displacements(supercell, cells_with_disps, optional_structure_info[1], num_unitcells_in_supercell, template_file="TEMPLATE")
def get_phonon_distrib_alist( prim_cell, NNN, T, seed_range, calc, cp_files=None, plus_minus=True, delta=0.01, ): """ prim_cell (str) ASE readable primitive unitcell structure file. NNN (list of int, shape: (3,3)) Supercell matrix used to calculate force constants. T (float) Temperature in Kelvin unit. seed_range (range or list of int) Seeds for random number generation. calc (str, choices: ('lmp', 'vasp')) Calculator for force calculation. cp_files (list of str) List of input files for force calculation. plus_minus (bool) Option handed to ASE function. delta (float) Displacement in Angstrom for finite displacement method. """ # Main from ase.io import read, write atoms = read(prim_cell) from phonopy import Phonopy phonon = Phonopy( atoms, NNN, ) phonon.generate_displacements( delta, ) pho_super = phonon.get_supercell() pho_disp = phonon.get_supercells_with_displacements() from phonopy.interface import vasp vasp.write_supercells_with_displacements( pho_super, pho_disp, ) import ss_phonopy as ssp phonon = ssp.calc_phonon( calc, phonon, cp_files=cp_files, ) masses = pho_super.masses job_name = 'eig_x{}{}{}_d{:5.3f}_sym{}'.format(NNN[0][0], NNN[1][1], NNN[2][2], delta, phonon._is_symmetry) try: e_s = np.load('{}.npz'.format(job_name)) except: print('Failed to load {}.npz file. Start to solve eigen problem.'.format(job_name)) eigen_set = get_eigen_set( phonon.get_force_constants(), masses, ) np.savez('{}.npz'.format(job_name), w2=eigen_set[0], D=eigen_set[1]) else: print('Successfully loaded {}.npz file!'.format(job_name)) eigen_set = (e_s['w2'], e_s['D']) from ase.md.velocitydistribution import phonon_harmonics from ase import Atoms, units alist = [] for i in seed_range: d_ac, v_ac = phonon_harmonics( None, masses, T *units.kB, eigen_set=eigen_set, # rng=np.random.rand, seed=i, quantum=True, plus_minus=plus_minus, # return_eigensolution=False, # failfast=True, ) new_super = Atoms( cell = pho_super.get_cell(), symbols = pho_super.get_chemical_symbols(), positions = pho_super.get_positions() + d_ac, velocities = v_ac, pbc = True, ) alist.append(new_super) return(alist)