def create_FORCE_SETS(interface_mode, force_filenames, symprec=1e-5, is_wien2k_p1=False, force_sets_zero_mode=False, disp_filename='disp.yaml', force_sets_filename='FORCE_SETS', log_level=0): if (interface_mode is None or interface_mode == 'vasp' or interface_mode == 'pwmat' or interface_mode == 'abinit' or interface_mode == 'elk' or interface_mode == 'pwscf' or interface_mode == 'siesta' or interface_mode == 'crystal'): disp_dataset = parse_disp_yaml(filename=disp_filename) num_atoms = disp_dataset['natom'] num_displacements = len(disp_dataset['first_atoms']) if force_sets_zero_mode: num_displacements += 1 force_sets = get_force_sets(interface_mode, num_atoms, num_displacements, force_filenames, disp_filename, verbose=(log_level > 0)) elif interface_mode == 'wien2k': disp_dataset, supercell = parse_disp_yaml(filename=disp_filename, return_cell=True) from phonopy.interface.wien2k import parse_set_of_forces num_displacements = len(disp_dataset['first_atoms']) if force_sets_zero_mode: num_displacements += 1 if _check_number_of_files(num_displacements, force_filenames, disp_filename): force_sets = [] else: disps = [[d['number'], d['displacement']] for d in disp_dataset['first_atoms']] force_sets = parse_set_of_forces(disps, force_filenames, supercell, is_distribute=(not is_wien2k_p1), symprec=symprec, verbose=(log_level > 0)) else: force_sets = [] if force_sets: if force_sets_zero_mode: force_sets = _subtract_residual_forces(force_sets) for forces, disp in zip(force_sets, disp_dataset['first_atoms']): disp['forces'] = forces write_FORCE_SETS(disp_dataset, filename=force_sets_filename) if log_level > 0: if force_sets: print("%s has been created." % force_sets_filename) else: print("%s could not be created." % force_sets_filename) return 0
def create_FORCE_SETS(forces_filenames, displacements, supercell, filename='FORCE_SETS', is_distribute=True, symprec=1e-5): natom = supercell.get_number_of_atoms() lattice = supercell.get_cell() for wien2k_filename, disp in zip(forces_filenames, displacements['first_atoms']): # Parse wien2k case.scf file wien2k_forces = get_forces_wien2k(wien2k_filename, lattice) if is_distribute: force_set = distribute_forces( supercell, [disp['number'], disp['displacement']], wien2k_forces, wien2k_filename, symprec) if not force_set: return False else: if not (natom == len(wien2k_forces)): print "%s contains only forces of %d atoms" % ( wien2k_filename, len(wien2k_forces)) return False else: force_set = wien2k_forces drift_force = get_drift_forces(force_set, filename=wien2k_filename) disp['forces'] = np.array(force_set) - drift_force write_FORCE_SETS(displacements, filename=filename) return True
def create_FORCE_SETS_from_FORCES_FCx_then_exit(phonon_smat, input_filename: Optional[str], cell_filename: Optional[str], log_level): """Convert FORCES_FC3 or FORCES_FC2 to FORCE_SETS.""" if cell_filename is not None: disp_filename = cell_filename elif input_filename is None: disp_filename = "phono3py_disp.yaml" else: disp_filename = f"phono3py_disp.{input_filename}.yaml" if phonon_smat is not None: forces_filename = "FORCES_FC2" else: forces_filename = "FORCES_FC3" if log_level: print(f'Displacement dataset is read from "{disp_filename}".') print(f'Forces are read from "{forces_filename}"') with open(forces_filename, "r") as f: len_first_line = get_length_of_first_line(f) if len_first_line == 3: file_exists(disp_filename, log_level) file_exists(forces_filename, log_level) ph3yml = Phono3pyYaml() ph3yml.read(disp_filename) if phonon_smat is None: dataset = copy.deepcopy(ph3yml.dataset) smat = ph3yml.supercell_matrix else: dataset = copy.deepcopy(ph3yml.phonon_dataset) smat = ph3yml.phonon_supercell_matrix if smat is None or (phonon_smat is not None and (phonon_smat != smat).any()): if log_level: print("") print("Supercell matrix is inconsistent.") print(f'Supercell matrix read from "{disp_filename}":') print(smat) print("Supercell matrix given by --dim-fc2:") print(phonon_smat) print_error() sys.exit(1) parse_FORCES_FC2(dataset, filename=forces_filename) write_FORCE_SETS(dataset) if log_level: print("FORCE_SETS has been created.") print_end() else: if log_level: print("The file format of %s is already readable by phonopy." % forces_filename) print_end() sys.exit(0)
def _write_FORCE_SETS(self, forces): displacements = [[x[0], x[1:4]] for x in self._phonon.get_displacements()] natom = self._phonon.get_supercell().get_number_of_atoms() write_FORCE_SETS("FORCE_SETS", natom, displacements, forces, verbose=False)
def write_force_sets(self, filename='FORCE_SETS'): """ Write the force sets in a file in phonopy plain text format :param filename: Force sets filename """ data_set = self.get_force_constants(include_data_set=True)[1] write_FORCE_SETS(data_set, filename=filename)
def _collect_forces(self): forces = [] for task in self._tasks: forces.append(task.get_properties()['forces'][-1]) if self._phonon.produce_force_constants(forces=forces): write_FORCE_SETS(self._phonon.get_displacement_dataset()) return True else: # This can be due to delay of writting file to file system. return False
def next(self): if self._stage == 0: if "next" in self._status: self._energy = self._tasks[0].get_energy() self._comment = "%s\\n%f" % ( self._tasks[0].get_space_group()['international'], self._energy) self._set_stage1() return self._tasks elif "terminate" in self._status and self._traverse == "restart": self._traverse = False self._set_stage0() return self._tasks else: raise StopIteration elif self._stage == 1: if "next" in self._status: disp_dataset = self._phonon_fc3.get_displacement_dataset() for disp1, task in zip(disp_dataset['first_atoms'], self._tasks): disp1['forces'] = task.get_properties()['forces'][-1] write_FORCE_SETS(disp_dataset) self._phonon.set_displacement_dataset(disp_dataset) self._phonon.produce_force_constants( calculate_full_force_constants=False) if self._exist_imaginary_mode(): self._status = "imaginary_mode" self._write_yaml() self._tasks = [] raise StopIteration else: self._set_stage2() return self._tasks elif "terminate" in self._status and self._traverse == "restart": self._reset_stage1() return self._tasks else: raise StopIteration elif self._stage == 2: if "next" in self._status: self._status = "done" forces_fc3 = [] for i, task in enumerate(self._phonon_fc3_tasks[1:]): forces_fc3.append(task.get_properties()['forces'][-1]) disp_dataset = self._phonon_fc3.get_displacement_dataset() write_FORCES_FC3(disp_dataset, forces_fc3) self._tasks = [] raise StopIteration elif "terminate" in self._status and self._traverse == "restart": self._reset_stage2() return self._tasks else: raise StopIteration else: # stage2 pass
def create_FORCE_SETS(interface_mode, force_filenames, symprec, is_wien2k_p1=False, force_sets_zero_mode=False, log_level=0): if (interface_mode is None or interface_mode == 'vasp' or interface_mode == 'abinit' or interface_mode == 'elk' or interface_mode == 'pwscf' or interface_mode == 'siesta'): displacements = parse_disp_yaml(filename='disp.yaml') num_atoms = displacements['natom'] if _check_number_of_files(displacements, force_filenames, force_sets_zero_mode): return 1 force_sets = _get_force_sets(interface_mode, num_atoms, force_filenames) elif interface_mode == 'wien2k': displacements, supercell = parse_disp_yaml(filename='disp.yaml', return_cell=True) from phonopy.interface.wien2k import parse_set_of_forces if _check_number_of_files(displacements, force_filenames, force_sets_zero_mode): return 1 force_sets = parse_set_of_forces( displacements, force_filenames, supercell, disp_keyword='first_atoms', is_distribute=(not is_wien2k_p1), symprec=symprec) else: force_sets = [] if force_sets: if force_sets_zero_mode: force_sets = _subtract_residual_forces(force_sets) for forces, disp in zip(force_sets, displacements['first_atoms']): disp['forces'] = forces write_FORCE_SETS(displacements, filename='FORCE_SETS') if log_level > 0: if force_sets: print("FORCE_SETS has been created.") else: print("FORCE_SETS could not be created.") return 0
def create_FORCE_SETS(interface_mode, force_filenames, symprec, is_wien2k_p1=False, log_level=0): if (interface_mode is None or interface_mode == 'vasp' or interface_mode == 'abinit' or interface_mode == 'elk' or interface_mode == 'pwscf' or interface_mode == 'siesta'): displacements = parse_disp_yaml(filename='disp.yaml') num_atoms = displacements['natom'] if len(displacements['first_atoms']) != len(force_filenames): print('') print("Number of files to be read don't match " "to number of displacements in disp.yaml.") return 1 force_sets = get_force_sets(interface_mode, num_atoms, force_filenames) elif interface_mode == 'wien2k': displacements, supercell = parse_disp_yaml(filename='disp.yaml', return_cell=True) if len(displacements['first_atoms']) != len(force_filenames): print('') print("Number of files to be read don't match " "to number of displacements in disp.yaml.") return 1 from phonopy.interface.wien2k import parse_set_of_forces force_sets = parse_set_of_forces( displacements, force_filenames, supercell, disp_keyword='first_atoms', is_distribute=(not is_wien2k_p1), symprec=symprec) else: force_sets = [] if force_sets: for forces, disp in zip(force_sets, displacements['first_atoms']): disp['forces'] = forces write_FORCE_SETS(displacements, filename='FORCE_SETS') if log_level > 0: if force_sets: print("FORCE_SETS has been created.") else: print("FORCE_SETS could not be created.") return 0
def create_FORCE_SETS(interface_mode, force_filenames, options, log_level=0): if (interface_mode == 'vasp' or interface_mode == 'abinit' or interface_mode == 'elk' or interface_mode == 'pwscf' or interface_mode == 'siesta'): displacements = parse_disp_yaml(filename='disp.yaml') num_atoms = displacements['natom'] if len(displacements['first_atoms']) != len(force_filenames): print('') print("Number of files to be read don't match " "to number of displacements in disp.yaml.") return 1 force_sets = get_force_sets(interface_mode, num_atoms, force_filenames) elif interface_mode == 'wien2k': displacements, supercell = parse_disp_yaml(filename='disp.yaml', return_cell=True) if len(displacements['first_atoms']) != len(force_filenames): print('') print("Number of files to be read don't match " "to number of displacements in disp.yaml.") return 1 from phonopy.interface.wien2k import parse_set_of_forces force_sets = parse_set_of_forces( displacements, force_filenames, supercell, disp_keyword='first_atoms', is_distribute=(not options.is_wien2k_p1), symprec=options.symprec) else: force_sets = [] if force_sets: for forces, disp in zip(force_sets, displacements['first_atoms']): disp['forces'] = forces write_FORCE_SETS(displacements, filename='FORCE_SETS') if log_level > 0: if force_sets: print("FORCE_SETS has been created.") else: print("FORCE_SETS could not be created.") return 0
def next(self): if self._stage == 0: if self._status == "next": self._energy = self._tasks[0].get_energy() num_atom = len(self._tasks[0].get_cell().get_symbols()) self._comment = self._space_group['international_standard'] self._comment += "\\n%f/%d" % (self._energy, num_atom) self._set_stage1() return self._tasks elif (self._status == "terminate" and self._traverse == "restart"): self._traverse = False self._set_stage0() return self._tasks else: # task 1..n: displaced supercells if self._status == "next": self._status = "done" forces = [] for task in self._tasks: forces.append(task.get_properties()['forces'][-1]) self._phonon.produce_force_constants(forces) write_FORCE_SETS(self._phonon.get_displacement_dataset()) self._tasks = [] elif self._status == "terminate" and self._traverse == "restart": self._traverse = False disp_terminated = [] for i, task in enumerate(self._tasks): if task.get_status() == "terminate": disp_terminated.append(i) tasks = self._get_displacement_tasks() self._tasks = [] for i in disp_terminated: self._tasks.append(tasks[i]) self._phonon_tasks[i + 1] = tasks[i] self._status = "displacements" return self._tasks self._write_yaml() raise StopIteration
def create_FORCE_SETS_from_FORCES_FCx_then_exit(phonon_smat, input_filename, log_level): if phonon_smat is not None: if input_filename is None: disp_filename = 'disp_fc2.yaml' else: disp_filename = 'disp_fc2.' + input_filename + '.yaml' forces_filename = "FORCES_FC2" else: if input_filename is None: disp_filename = 'disp_fc3.yaml' else: disp_filename = 'disp_fc3.' + input_filename + '.yaml' forces_filename = "FORCES_FC3" with open(forces_filename, 'r') as f: len_first_line = get_length_of_first_line(f) if len_first_line == 3: file_exists(disp_filename, log_level) disp_dataset = parse_disp_fc2_yaml(filename=disp_filename) file_exists(forces_filename, log_level) parse_FORCES_FC2(disp_dataset, filename=forces_filename) if log_level: print("Displacement dataset was read from \"%s\"." % disp_filename) write_FORCE_SETS(disp_dataset) if log_level: print("FORCE_SETS has been created.") print_end() else: if log_level: print("The file format of %s is already readable by phonopy." % forces_filename) print_end() sys.exit(0)
def create_FORCE_SETS(interface_mode, force_filenames, options, log_level): if interface_mode == 'vasp': displacements = parse_disp_yaml(filename='disp.yaml') if (interface_mode == 'wien2k' or interface_mode == 'abinit' or interface_mode == 'pwscf'): displacements, supercell = parse_disp_yaml(filename='disp.yaml', return_cell=True) num_disp_files = len(force_filenames) if options.force_sets_zero_mode: num_disp_files -= 1 if len(displacements['first_atoms']) != num_disp_files: print print ("Number of files to be read don't match " "to number of displacements in disp.yaml.") return 1 if interface_mode == 'vasp': from phonopy.interface.vasp import parse_set_of_forces is_parsed = parse_set_of_forces( displacements, force_filenames, is_zero_point=options.force_sets_zero_mode) if interface_mode == 'abinit': from phonopy.interface.abinit import parse_set_of_forces print "**********************************************************" print "**** Abinit FORCE_SETS support is experimental. ****" print "**** Your feedback would be appreciated. ****" print "**********************************************************" is_parsed = parse_set_of_forces( displacements, force_filenames, supercell.get_number_of_atoms()) if interface_mode == 'pwscf': from phonopy.interface.pwscf import parse_set_of_forces print "**********************************************************" print "**** Pwscf FORCE_SETS support is experimental. ****" print "**** Your feedback would be appreciated. ****" print "**********************************************************" is_parsed = parse_set_of_forces( displacements, force_filenames, supercell.get_number_of_atoms()) if interface_mode == 'wien2k': from phonopy.interface.wien2k import parse_set_of_forces print "**********************************************************" print "**** Wien2k FORCE_SETS support is experimental. ****" print "**** Your feedback would be appreciated. ****" print "**********************************************************" is_parsed = parse_set_of_forces( displacements, force_filenames, supercell, is_distribute=(not options.is_wien2k_p1), symprec=options.symprec) if is_parsed: write_FORCE_SETS(displacements, filename='FORCE_SETS') if log_level > 0: if is_parsed: print "FORCE_SETS has been created." else: print "FORCE_SETS could not be created." return 0
def create_FORCE_SETS(interface_mode, force_filenames, options, log_level): if interface_mode == 'vasp': displacements = parse_disp_yaml(filename='disp.yaml') if (interface_mode == 'wien2k' or interface_mode == 'abinit' or interface_mode == 'pwscf'): displacements, supercell = parse_disp_yaml(filename='disp.yaml', return_cell=True) num_disp_files = len(force_filenames) if options.force_sets_zero_mode: num_disp_files -= 1 if len(displacements['first_atoms']) != num_disp_files: print print( "Number of files to be read don't match " "to number of displacements in disp.yaml.") return 1 if interface_mode == 'vasp': from phonopy.interface.vasp import parse_set_of_forces is_parsed = parse_set_of_forces( displacements, force_filenames, is_zero_point=options.force_sets_zero_mode) if interface_mode == 'abinit': from phonopy.interface.abinit import parse_set_of_forces print "**********************************************************" print "**** Abinit FORCE_SETS support is experimental. ****" print "**** Your feedback would be appreciated. ****" print "**********************************************************" is_parsed = parse_set_of_forces(displacements, force_filenames, supercell.get_number_of_atoms()) if interface_mode == 'pwscf': from phonopy.interface.pwscf import parse_set_of_forces print "**********************************************************" print "**** Pwscf FORCE_SETS support is experimental. ****" print "**** Your feedback would be appreciated. ****" print "**********************************************************" is_parsed = parse_set_of_forces(displacements, force_filenames, supercell.get_number_of_atoms()) if interface_mode == 'wien2k': from phonopy.interface.wien2k import parse_set_of_forces print "**********************************************************" print "**** Wien2k FORCE_SETS support is experimental. ****" print "**** Your feedback would be appreciated. ****" print "**********************************************************" is_parsed = parse_set_of_forces( displacements, force_filenames, supercell, is_distribute=(not options.is_wien2k_p1), symprec=options.symprec) if is_parsed: write_FORCE_SETS(displacements, filename='FORCE_SETS') if log_level > 0: if is_parsed: print "FORCE_SETS has been created." else: print "FORCE_SETS could not be created." return 0
def phonopy_run(phonon, single=True, filename='FORCE_SETS'): """Run the phonon calculations, using PhonoPy. The force constants are then stored in the Phonon ASE object. input: phonon: ASE Phonon object with Atoms and Calculator single: when True, the forces are computed only for a single step, and then exit. This allows to split the loop in independent iterations. When calling again the 'run' method, already computed steps are ignored, missing steps are completed, until no more are needed. When set to False, all steps are done in a row. output: True when a calculation step was performed, False otherwise or no more is needed. nb_of_iterations: the number of steps remaining """ from phonopy import Phonopy from phonopy.structure.atoms import Atoms as PAtoms from phonopy.structure.atoms import PhonopyAtoms import phonopy.file_IO as file_IO # we first look if an existing phonon pickle exists. This is the case if we # are running with iterative calls while return value is True. The first call # will then create the objects, which are subsequently updated until False. # Set calculator if provided # assert phonon.calc is not None, "Provide calculator in Phonon __init__ method" # Atoms in the supercell -- repeated in the lattice vector directions # beginning with the last supercell = phonon.atoms * phonon.N_c # create a PhonopyAtoms object cell = PhonopyAtoms(phonon.atoms.get_chemical_symbols(), positions=phonon.atoms.get_positions(), cell=phonon.atoms.get_cell(), magmoms=None) # is there an existing PhonoPy calculation ? # using factor=6.46541380e-2=VaspToeV if os.path.exists('FORCE_SETS'): phonpy = Phonopy(cell, numpy.diag(phonon.N_c), primitive_matrix=None, dynamical_matrix_decimals=None, force_constants_decimals=None, symprec=1e-05, is_symmetry=True, use_lapack_solver=False, log_level=1) force_sets = file_IO.parse_FORCE_SETS(filename='FORCE_SETS') phonpy.set_displacement_dataset(force_sets) # inactivate magmoms in supercell as some calculators do not provide that phonpy._supercell.magmoms = None phonpy.produce_force_constants(calculate_full_force_constants=False) else: # create a PhonoPy Phonon object. phonpy = Phonopy(cell, numpy.diag(phonon.N_c)) # generate displacements (minimal set) phonpy.generate_displacements(distance=0.01) # iterative call for all displacements set_of_forces, flag, nb_of_iterations = phonopy_run_calculate( phonon, phonpy, supercell, single) if flag is True: return nb_of_iterations # some more work is required sys.stdout.write('[ASE/Phonopy] Computing force constants\n') # use symmetry to derive forces in equivalent displacements phonpy.produce_force_constants(forces=set_of_forces) # generate disp.yaml and FORCE_SETS (for later use) displacements = phonpy.get_displacements() directions = phonpy.get_displacement_directions() file_IO.write_disp_yaml(displacements, phonpy.get_supercell(), directions=directions) file_IO.write_FORCE_SETS(phonpy.get_displacement_dataset()) # store as additional data in atoms 'info' phonon.atoms.info["phonopy"] = phonpy # save the PhonoPy object fid = opencew("phonopy.pkl") if fid is not None and rank == 0: print("[ASE/Phonopy] Writing %s" % "phonopy.pkl") pickle.dump(phonpy, fid, protocol=2) fid.close() # transfer results to the ASE phonon object # Number of atoms (primitive cell) natoms = len(phonon.indices) # Number of unit cells (supercell) N = numpy.prod(phonon.N_c) # Phonopy: force_constants size is [N*natoms,N*natoms,3,3] # Phi[i,j,a,b] with [i,j = atom in supercell] and [a,b=xyz] force_constants = phonpy.get_force_constants() # the atoms [i] which are moved are in the first cell of the supercell, i.e.Ni=0 # the forces are then stored for all atoms [Nj,j] as [3,3] matrices # we compute the sum on all supercells, which all contain n atoms. C_N = numpy.zeros((N, 3 * natoms, 3 * natoms), dtype=complex) Ni = 0 for Nj in range(N): for ni in range(natoms): Nni = ni for nj in range(natoms): # compute Nn indices Nnj = Nj * natoms + nj # get fc 3x3 matrix C_N[Nj, (3 * ni):(3 * ni + 3), (3 * nj):(3 * nj + 3)] += force_constants[Nni][Nnj] # convert to ASE storage # ASE: phonon.C_N size is be [N, 3*natoms, 3*natoms] # Phi[i,j] = Phi[j,i] phonon.C_N = C_N # fill dynamical matrix (mass prefactor) phonon.D_N = phonon.C_N.copy() # Add mass prefactor m_a = phonon.atoms.get_masses() phonon.m_inv_x = numpy.repeat(m_a[phonon.indices]**-0.5, 3) M_inv = numpy.outer(phonon.m_inv_x, phonon.m_inv_x) for D in phonon.D_N: D *= M_inv return 0 # nothing left to do
def create_FORCE_SETS(interface_mode, force_filenames, symmetry_tolerance=None, is_wien2k_p1=False, force_sets_zero_mode=False, disp_filename='disp.yaml', force_sets_filename='FORCE_SETS', log_level=0): if log_level > 0: if interface_mode: print("Calculator interface: %s" % interface_mode) print("Displacements were read from \"%s\"." % disp_filename) if disp_filename == 'disp.yaml': print('') print("NOTE:") print(" From phonopy v2.0, displacements are written into " "\"phonopy_disp.yaml\".") print(" \"disp.yaml\" is still supported for reading, but is " "deprecated.") print('') if force_sets_zero_mode: print("Forces in %s are subtracted from forces in all " "other files." % force_filenames[0]) if interface_mode in (None, 'vasp', 'abinit', 'elk', 'qe', 'siesta', 'cp2k', 'crystal', 'dftbp', 'turbomole'): disp_dataset = parse_disp_yaml(filename=disp_filename) num_atoms = disp_dataset['natom'] num_displacements = len(disp_dataset['first_atoms']) if force_sets_zero_mode: num_displacements += 1 force_sets = get_force_sets(interface_mode, num_atoms, num_displacements, force_filenames, disp_filename=disp_filename, check_number_of_files=True, verbose=(log_level > 0)) elif interface_mode == 'wien2k': disp_dataset, supercell = parse_disp_yaml(filename=disp_filename, return_cell=True) from phonopy.interface.wien2k import parse_set_of_forces num_displacements = len(disp_dataset['first_atoms']) if force_sets_zero_mode: num_displacements += 1 if _check_number_of_files(num_displacements, force_filenames, disp_filename): force_sets = [] else: disps = [[d['number'], d['displacement']] for d in disp_dataset['first_atoms']] force_sets = parse_set_of_forces( disps, force_filenames, supercell, is_distribute=(not is_wien2k_p1), symmetry_tolerance=symmetry_tolerance, verbose=(log_level > 0)) else: force_sets = [] if force_sets: if force_sets_zero_mode: force_sets = _subtract_residual_forces(force_sets) for forces, disp in zip(force_sets, disp_dataset['first_atoms']): disp['forces'] = forces write_FORCE_SETS(disp_dataset, filename=force_sets_filename) if log_level > 0: if force_sets: print("%s has been created." % force_sets_filename) else: print("%s could not be created." % force_sets_filename) return 0
def create_FORCE_SETS( interface_mode, force_filenames, symmetry_tolerance=None, wien2k_P1_mode=False, force_sets_zero_mode=False, disp_filename="disp.yaml", force_sets_filename="FORCE_SETS", write_forcesets_yaml=False, log_level=0, ): """Create FORCE_SETS from phonopy_disp.yaml and calculator output files. Reading disp.yaml instead of phonopy_disp.yaml is deprecated. """ if log_level > 0: if interface_mode: print("Calculator interface: %s" % interface_mode) print('Displacements were read from "%s".' % disp_filename) if disp_filename == "disp.yaml": print("") print("NOTE:") print(" From phonopy v2.0, displacements are written into " '"phonopy_disp.yaml".') print(' "disp.yaml" is still supported for reading except for ' "Wien2k interface, ") print(" but is deprecated.") print("") if force_sets_zero_mode: print("Forces in %s are subtracted from forces in all " "other files." % force_filenames[0]) if disp_filename == "disp.yaml": if interface_mode == "wien2k": disp_dataset, supercell = parse_disp_yaml(filename=disp_filename, return_cell=True) else: disp_dataset = parse_disp_yaml(filename=disp_filename) else: phpy_yaml = PhonopyYaml() phpy_yaml.read(disp_filename) supercell = phpy_yaml.supercell disp_dataset = phpy_yaml.dataset if "natom" in disp_dataset: # type-1 dataset num_atoms = disp_dataset["natom"] num_displacements = len(disp_dataset["first_atoms"]) dataset_type = 1 elif "displacements" in disp_dataset: # type-2 dataset num_atoms = disp_dataset["displacements"].shape[1] num_displacements = disp_dataset["displacements"].shape[0] dataset_type = 2 else: raise RuntimeError("Number of atoms could not be retrieved from %s" % disp_filename) if force_sets_zero_mode: num_displacements += 1 if not check_number_of_force_files(num_displacements, force_filenames, disp_filename): force_sets = [] elif interface_mode == "wien2k": force_sets = get_force_sets_wien2k( force_filenames, supercell, disp_dataset, wien2k_P1_mode=wien2k_P1_mode, symmetry_tolerance=symmetry_tolerance, verbose=(log_level > 0), ) else: force_sets = get_force_sets( interface_mode, num_atoms, force_filenames, verbose=(log_level > 0), ) if force_sets: if force_sets_zero_mode: force_sets = _subtract_residual_forces(force_sets) if dataset_type == 1: for forces, disp in zip(force_sets, disp_dataset["first_atoms"]): disp["forces"] = forces elif dataset_type == 2: disp_dataset["forces"] = np.array(force_sets, dtype="double", order="C") else: raise RuntimeError("FORCE_SETS could not be created.") write_FORCE_SETS(disp_dataset, filename=force_sets_filename) if log_level > 0: print('"%s" has been created.' % force_sets_filename) if disp_filename != "disp.yaml" and write_forcesets_yaml: phpy_yaml.dataset = disp_dataset with open("phonopy_force_sets.yaml", "w") as w: w.write(str(phpy_yaml)) if log_level > 0: print('"%s" has been created.' % "phonopy_force_sets.yaml") else: if log_level > 0: print("%s could not be created." % force_sets_filename)
def on_all_ok(self): """ This method is called once the `Work` is completed i.e. when all the tasks have reached status S_OK. Here we get the forces from the output files, and we call phonopy to compute the inter-atomic force constants. """ phonon = self.phonon # Write POSCAR with initial unit cell. structure = structure_from_atoms(phonon.get_primitive()) structure.to(filename=self.outdir.path_in("POSCAR")) # Write yaml file with displacements. supercell = phonon.get_supercell() displacements = phonon.get_displacements() #directions = phonon.get_displacement_directions() file_IO.write_disp_yaml( displacements, supercell, # directions=directions, filename=self.outdir.path_in('disp.yaml')) # Extract forces from the main Abinit output files. forces_filenames = [ task.output_file.path for task in self.phonopy_tasks ] num_atoms = supercell.get_number_of_atoms() force_sets = parse_set_of_forces(num_atoms, forces_filenames) # Write FORCE_SETS file. displacements = file_IO.parse_disp_yaml( filename=self.outdir.path_in('disp.yaml')) num_atoms = displacements['natom'] for forces, disp in zip(force_sets, displacements['first_atoms']): disp['forces'] = forces file_IO.write_FORCE_SETS(displacements, filename=self.outdir.path_in('FORCE_SETS')) # Write README and configuration files. examples_url = "http://atztogo.github.io/phonopy/examples.html" doctags_url = "http://atztogo.github.io/phonopy/setting-tags.html#setting-tags" kptbounds = np.array([k.frac_coords for k in structure.hsym_kpoints]) path_coords = " ".join(str(rc) for rc in kptbounds.flat) path_labels = " ".join(k.name for k in structure.hsym_kpoints) ngqpt = structure.calc_ngkpt(nksmall=30) with open(self.outdir.path_in("band.conf"), "wt") as fh: fh.write("#" + doctags_url + "\n") fh.write("DIM = %d %d %d\n" % tuple(self.scdims)) fh.write("BAND = %s\n" % path_coords) fh.write("BAND_LABELS = %s\n" % path_labels) fh.write("BAND_POINTS = 101\n") fh.write("#BAND_CONNECTION = .TRUE.\n") with open(self.outdir.path_in("dos.conf"), "wt") as fh: fh.write("#" + doctags_url + "\n") fh.write("DIM = %d %d %d\n" % tuple(self.scdims)) fh.write("MP = %d %d %d\n" % tuple(ngqpt)) fh.write("#GAMMA_CENTER = .TRUE.\n") with open(self.outdir.path_in("band-dos.conf"), "wt") as fh: fh.write("#" + doctags_url + "\n") fh.write("DIM = %d %d %d\n" % tuple(self.scdims)) fh.write("BAND = %s\n" % path_coords) fh.write("BAND_LABELS = %s\n" % path_labels) fh.write("BAND_POINTS = 101\n") fh.write("#BAND_CONNECTION = .TRUE.\n") fh.write("MP = %d %d %d\n" % tuple(ngqpt)) fh.write("#GAMMA_CENTER = .TRUE.\n") with open(self.outdir.path_in("README.md"), "wt") as fh: fh.write("To plot bands, use:\n\tphonopy -p band.conf\n\n") fh.write("To plot phonon dos, use:\n\tphonopy -p dos.conf\n\n") fh.write( "To plot bands and dos, use:\n\tphonopy -p band-dos.conf\n\n") fh.write("See also:\n") fh.write("\t" + examples_url + "\n") fh.write("\t" + doctags_url + "\n") if self.cpdata2dst: self.outdir.copy_r(self.cpdata2dst) return super(PhonopyWork, self).on_all_ok()
def create_FORCE_SETS(interface_mode, force_filenames, options, log_level): if interface_mode == "vasp": displacements = parse_disp_yaml(filename="disp.yaml") if ( interface_mode == "wien2k" or interface_mode == "abinit" or interface_mode == "elk" or interface_mode == "pwscf" or interface_mode == "siesta" ): displacements, supercell = parse_disp_yaml(filename="disp.yaml", return_cell=True) num_disp_files = len(force_filenames) if options.force_sets_zero_mode: num_disp_files -= 1 if len(displacements["first_atoms"]) != num_disp_files: print("") print("Number of files to be read don't match " "to number of displacements in disp.yaml.") return 1 if interface_mode == "vasp": from phonopy.interface.vasp import parse_set_of_forces is_parsed = parse_set_of_forces(displacements, force_filenames, is_zero_point=options.force_sets_zero_mode) if interface_mode == "abinit": from phonopy.interface.abinit import parse_set_of_forces print("**********************************************************") print("**** Abinit FORCE_SETS support is experimental. ****") print("**** Your feedback would be appreciated. ****") print("**********************************************************") is_parsed = parse_set_of_forces(displacements, force_filenames, supercell.get_number_of_atoms()) if interface_mode == "pwscf": from phonopy.interface.pwscf import parse_set_of_forces print("**********************************************************") print("**** Pwscf FORCE_SETS support is experimental. ****") print("**** Your feedback would be appreciated. ****") print("**********************************************************") is_parsed = parse_set_of_forces(displacements, force_filenames, supercell.get_number_of_atoms()) if interface_mode == "wien2k": from phonopy.interface.wien2k import parse_set_of_forces print("**********************************************************") print("**** Wien2k FORCE_SETS support is experimental. ****") print("**** Your feedback would be appreciated. ****") print("**********************************************************") is_parsed = parse_set_of_forces( displacements, force_filenames, supercell, is_distribute=(not options.is_wien2k_p1), symprec=options.symprec ) if interface_mode == "elk": from phonopy.interface.elk import parse_set_of_forces print("**********************************************************") print("**** Elk FORCE_SETS support is experimental. ****") print("**** Your feedback would be appreciated. ****") print("**********************************************************") is_parsed = parse_set_of_forces(displacements, force_filenames, supercell.get_number_of_atoms()) if interface_mode == "siesta": from phonopy.interface.siesta import parse_set_of_forces print("**********************************************************") print("**** Siesta FORCE_SETS support is experimental. ****") print("**** Your feedback would be appreciated. ****") print("**********************************************************") is_parsed = parse_set_of_forces(displacements, force_filenames, supercell.get_number_of_atoms()) if is_parsed: write_FORCE_SETS(displacements, filename="FORCE_SETS") if log_level > 0: if is_parsed: print("FORCE_SETS has been created.") else: print("FORCE_SETS could not be created.") return 0
phonon_scell.generate_displacements(distance=0.03) # vasp Scells_phonopy = phonon_scell.get_supercells_with_displacements( ) # This returns a list of Phononpy atoms object # convert phonopy atoms objects to quippy atom objects Scells_quippy = [] for scell in Scells_phonopy: scell_qp = api_ph.phonopyAtoms_to_aseAtoms(scell) Scells_quippy.append(scell_qp) # calculate forces and convert to phonopy force_sets force_gap_scells = api_q.calc_force_sets_GAP(gp_xml_file, Scells_quippy) #parse force set and calc force constants phonon_scell.set_forces(force_gap_scells) PhonIO.write_FORCE_SETS(phonon_scell.get_displacement_dataset() ) # write forces & displacements to FORCE_SET force_set = PhonIO.parse_FORCE_SETS() # parse force_sets phonon_scell.set_displacement_dataset( force_set) # force_set is a list of forces and displacements if NAC == True: nac_params = PhonIO.get_born_parameters( open("BORN"), phonon_scell.get_primitive(), phonon_scell.get_primitive_symmetry()) if nac_params['factor'] == None: physical_units = get_default_physical_units(interface_mode) nac_params['factor'] = physical_units['nac_factor'] phonon_scell._nac_params = nac_params phonon_scell.produce_force_constants() phonon_scell.symmetrize_force_constants()
def on_all_ok(self): """ This method is called once the `Work` is completed i.e. when all the tasks have reached status S_OK. Here we get the forces from the output files, and we call phonopy to compute the inter-atomic force constants. """ phonon = self.phonon # Write POSCAR with initial unit cell. structure = structure_from_atoms(phonon.get_primitive()) structure.to(filename=self.outdir.path_in("POSCAR")) # Write yaml file with displacements. supercell = phonon.get_supercell() displacements = phonon.get_displacements() #directions = phonon.get_displacement_directions() file_IO.write_disp_yaml(displacements, supercell, # directions=directions, filename=self.outdir.path_in('disp.yaml')) # Extract forces from the main Abinit output files. forces_filenames = [task.output_file.path for task in self.phonopy_tasks] num_atoms = supercell.get_number_of_atoms() force_sets = parse_set_of_forces(num_atoms, forces_filenames) # Write FORCE_SETS file. displacements = file_IO.parse_disp_yaml(filename=self.outdir.path_in('disp.yaml')) num_atoms = displacements['natom'] for forces, disp in zip(force_sets, displacements['first_atoms']): disp['forces'] = forces file_IO.write_FORCE_SETS(displacements, filename=self.outdir.path_in('FORCE_SETS')) # Write README and configuration files. examples_url = "http://atztogo.github.io/phonopy/examples.html" doctags_url = "http://atztogo.github.io/phonopy/setting-tags.html#setting-tags" kptbounds = np.array([k.frac_coords for k in structure.hsym_kpoints]) path_coords = " ".join(str(rc) for rc in kptbounds.flat) path_labels = " ".join(k.name for k in structure.hsym_kpoints) ngqpt = structure.calc_ngkpt(nksmall=30) with open(self.outdir.path_in("band.conf"), "wt") as fh: fh.write("#" + doctags_url + "\n") fh.write("DIM = %d %d %d\n" % tuple(self.scdims)) fh.write("BAND = %s\n" % path_coords) fh.write("BAND_LABELS = %s\n" % path_labels) fh.write("BAND_POINTS = 101\n") fh.write("#BAND_CONNECTION = .TRUE.\n") with open(self.outdir.path_in("dos.conf"), "wt") as fh: fh.write("#" + doctags_url + "\n") fh.write("DIM = %d %d %d\n" % tuple(self.scdims)) fh.write("MP = %d %d %d\n" % tuple(ngqpt)) fh.write("#GAMMA_CENTER = .TRUE.\n") with open(self.outdir.path_in("band-dos.conf"), "wt") as fh: fh.write("#" + doctags_url + "\n") fh.write("DIM = %d %d %d\n" % tuple(self.scdims)) fh.write("BAND = %s\n" % path_coords) fh.write("BAND_LABELS = %s\n" % path_labels) fh.write("BAND_POINTS = 101\n") fh.write("#BAND_CONNECTION = .TRUE.\n") fh.write("MP = %d %d %d\n" % tuple(ngqpt)) fh.write("#GAMMA_CENTER = .TRUE.\n") with open(self.outdir.path_in("README.md"), "wt") as fh: fh.write("To plot bands, use:\n\tphonopy -p band.conf\n\n") fh.write("To plot phonon dos, use:\n\tphonopy -p dos.conf\n\n") fh.write("To plot bands and dos, use:\n\tphonopy -p band-dos.conf\n\n") fh.write("See also:\n") fh.write("\t" + examples_url + "\n") fh.write("\t" + doctags_url + "\n") if self.cpdata2dst: self.outdir.copy_r(self.cpdata2dst) return super(PhonopyWork, self).on_all_ok()
def create_FORCE_SETS(interface_mode, force_filenames, symprec=1e-5, is_wien2k_p1=False, force_sets_zero_mode=False, disp_filename='disp.yaml', force_sets_filename='FORCE_SETS', log_level=0): if (interface_mode is None or interface_mode == 'vasp' or interface_mode == 'abinit' or interface_mode == 'elk' or interface_mode == 'lmto' or interface_mode == 'qe' or interface_mode == 'siesta' or interface_mode == 'cp2k' or interface_mode == 'crystal'): disp_dataset = parse_disp_yaml(filename=disp_filename) num_atoms = disp_dataset['natom'] num_displacements = len(disp_dataset['first_atoms']) if force_sets_zero_mode: num_displacements += 1 force_sets = get_force_sets(interface_mode, num_atoms, num_displacements, force_filenames, disp_filename, verbose=(log_level > 0)) elif interface_mode == 'wien2k': disp_dataset, supercell = parse_disp_yaml(filename=disp_filename, return_cell=True) from phonopy.interface.wien2k import parse_set_of_forces num_displacements = len(disp_dataset['first_atoms']) if force_sets_zero_mode: num_displacements += 1 if _check_number_of_files(num_displacements, force_filenames, disp_filename): force_sets = [] else: disps = [[d['number'], d['displacement']] for d in disp_dataset['first_atoms']] force_sets = parse_set_of_forces( disps, force_filenames, supercell, is_distribute=(not is_wien2k_p1), symprec=symprec, verbose=(log_level > 0)) else: force_sets = [] if force_sets: if force_sets_zero_mode: force_sets = _subtract_residual_forces(force_sets) for forces, disp in zip(force_sets, disp_dataset['first_atoms']): disp['forces'] = forces write_FORCE_SETS(disp_dataset, filename=force_sets_filename) if log_level > 0: if force_sets: print("%s has been created." % force_sets_filename) else: print("%s could not be created." % force_sets_filename) return 0
def create_FORCE_SETS(interface_mode, force_filenames, symmetry_tolerance=None, is_wien2k_p1=False, force_sets_zero_mode=False, disp_filename='disp.yaml', force_sets_filename='FORCE_SETS', log_level=0): if log_level > 0: if interface_mode: print("Calculator interface: %s" % interface_mode) print("Displacements were read from \"%s\"." % disp_filename) if disp_filename == 'disp.yaml': print('') print("NOTE:") print(" From phonopy v2.0, displacements are written into " "\"phonopy_disp.yaml\".") print(" \"disp.yaml\" is still supported for reading, but is " "deprecated.") print('') if force_sets_zero_mode: print("Forces in %s are subtracted from forces in all " "other files." % force_filenames[0]) if disp_filename == 'disp.yaml': disp_dataset, supercell = parse_disp_yaml(filename=disp_filename, return_cell=True) else: phpy = PhonopyYaml() phpy.read(disp_filename) supercell = phpy.supercell disp_dataset = phpy.dataset if 'natom' in disp_dataset: # type-1 dataset num_atoms = disp_dataset['natom'] num_displacements = len(disp_dataset['first_atoms']) dataset_type = 1 elif 'displacements' in disp_dataset: # type-2 dataset num_atoms = disp_dataset['displacements'].shape[1] num_displacements = disp_dataset['displacements'].shape[0] dataset_type = 2 else: raise RuntimeError("Number of atoms could not be retrieved from %s" % disp_filename) if force_sets_zero_mode: num_displacements += 1 if interface_mode in (None, 'vasp', 'abinit', 'elk', 'qe', 'siesta', 'cp2k', 'crystal', 'dftbp', 'turbomole'): force_sets = get_force_sets(interface_mode, num_atoms, num_displacements, force_filenames, disp_filename=disp_filename, check_number_of_files=True, verbose=(log_level > 0)) elif interface_mode == 'wien2k': from phonopy.interface.wien2k import parse_set_of_forces if not _check_number_of_files(num_displacements, force_filenames, disp_filename): force_sets = [] else: disps, _ = get_displacements_and_forces(disp_dataset) force_sets = parse_set_of_forces( disps, force_filenames, supercell, is_distribute=(not is_wien2k_p1), symmetry_tolerance=symmetry_tolerance, verbose=(log_level > 0)) else: force_sets = [] if force_sets: if force_sets_zero_mode: force_sets = _subtract_residual_forces(force_sets) if dataset_type == 1: for forces, disp in zip(force_sets, disp_dataset['first_atoms']): disp['forces'] = forces elif dataset_type == 2: disp_dataset['forces'] = np.array(force_sets, dtype='double', order='C') else: raise RuntimeError("FORCE_SETS could not be created.") write_FORCE_SETS(disp_dataset, filename=force_sets_filename) if log_level > 0: if force_sets: print("%s has been created." % force_sets_filename) else: print("%s could not be created." % force_sets_filename) return 0
def create_FORCE_SETS(interface_mode, force_filenames, symmetry_tolerance=None, wien2k_P1_mode=False, force_sets_zero_mode=False, disp_filename='disp.yaml', force_sets_filename='FORCE_SETS', log_level=0): """Create FORCE_SETS from phonopy_disp.yaml and calculator output files. Reading disp.yaml instead of phonopy_disp.yaml is deprecated. """ if log_level > 0: if interface_mode: print("Calculator interface: %s" % interface_mode) print("Displacements were read from \"%s\"." % disp_filename) if disp_filename == 'disp.yaml': print('') print("NOTE:") print(" From phonopy v2.0, displacements are written into " "\"phonopy_disp.yaml\".") print(" \"disp.yaml\" is still supported for reading except for " "Wien2k interface, ") print(" but is deprecated.") print('') if force_sets_zero_mode: print("Forces in %s are subtracted from forces in all " "other files." % force_filenames[0]) if disp_filename == 'disp.yaml': if interface_mode == 'wien2k': disp_dataset, supercell = parse_disp_yaml(filename=disp_filename, return_cell=True) else: disp_dataset = parse_disp_yaml(filename=disp_filename) else: phpy = PhonopyYaml() phpy.read(disp_filename) supercell = phpy.supercell disp_dataset = phpy.dataset if 'natom' in disp_dataset: # type-1 dataset num_atoms = disp_dataset['natom'] num_displacements = len(disp_dataset['first_atoms']) dataset_type = 1 elif 'displacements' in disp_dataset: # type-2 dataset num_atoms = disp_dataset['displacements'].shape[1] num_displacements = disp_dataset['displacements'].shape[0] dataset_type = 2 else: raise RuntimeError("Number of atoms could not be retrieved from %s" % disp_filename) if force_sets_zero_mode: num_displacements += 1 if not check_number_of_force_files(num_displacements, force_filenames, disp_filename): force_sets = [] elif interface_mode == 'wien2k': force_sets = get_force_sets_wien2k( num_displacements, force_filenames, disp_filename, supercell, disp_dataset, wien2k_P1_mode=wien2k_P1_mode, symmetry_tolerance=symmetry_tolerance, verbose=(log_level > 0)) else: force_sets = get_force_sets(interface_mode, num_atoms, num_displacements, force_filenames, disp_filename=disp_filename, verbose=(log_level > 0)) if force_sets: if force_sets_zero_mode: force_sets = _subtract_residual_forces(force_sets) if dataset_type == 1: for forces, disp in zip(force_sets, disp_dataset['first_atoms']): disp['forces'] = forces elif dataset_type == 2: disp_dataset['forces'] = np.array(force_sets, dtype='double', order='C') else: raise RuntimeError("FORCE_SETS could not be created.") write_FORCE_SETS(disp_dataset, filename=force_sets_filename) if log_level > 0: if force_sets: print("%s has been created." % force_sets_filename) else: print("%s could not be created." % force_sets_filename) return 0