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(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 read_phonopy(sposcar='SPOSCAR', sc_mat=np.eye(3), force_constants=None, disp_yaml=None, force_sets=None): if force_constants is None and (disp_yaml is None or force_sets is None): raise ValueError( "Either FORCE_CONSTANTS or (disp.yaml&FORCE_SETS) file should be provided." ) atoms = read(sposcar) #vesta_view(atoms) primitive_matrix = inv(sc_mat) bulk = PhonopyAtoms(symbols=atoms.get_chemical_symbols(), scaled_positions=atoms.get_scaled_positions(), cell=atoms.get_cell()) phonon = Phonopy( bulk, supercell_matrix=np.eye(3), primitive_matrix=primitive_matrix, #factor=factor, #symprec=symprec ) if disp_yaml is not None: disp = parse_disp_yaml(filename=disp_yaml) phonon.set_displacement_dataset(disp) if force_sets is not None: fc = parse_FORCE_SETS(filename=force_sets) phonon.set_forces(fc) fc = parse_FORCE_CONSTANTS(force_constants) phonon.set_force_constants(fc) return phonon
def test_parse_wien2k_struct(self): cell, npts, r0s, rmts = parse_wien2k_struct("BaGa2.struct") lattice = cell.get_cell().T displacements, supercell = parse_disp_yaml("disp_BaGa2.yaml", return_cell=True) symmetry = Symmetry(cell) print(PhonopyAtoms(atoms=cell)) sym_op = symmetry.get_symmetry_operations() print(symmetry.get_international_table()) for i, (r, t) in enumerate( zip(sym_op['rotations'], sym_op['translations'])): print("--- %d ---" % (i + 1)) print(r) print(t)
def parse_set_of_forces(num_atoms, forces_filenames, verbose=False): hook = 'CONVERGED' force_sets = [] for fplo_filename in forces_filenames: fplo_forces = iter_collect_forces(fplo_filename, num_atoms, hook, [6, 7, 8], word='TOTAL NEUTRAL FORCES') # rotate forces from the FPLO xyz coordinate system # into the coordinate system of phonopy # read the phonopy lattice vectors conf, cell = parse_disp_yaml(return_cell=True) ppy_lat = cell.get_cell() # read the fplo output file f = open(fplo_filename, 'r') outf = f.readlines() f.close # search lattice vectors fp_lat = np.zeros((3, 3)) for j in np.arange(len(outf)): if outf[j].find("lattice vectors") == 0: for i in np.arange(3): fp_lat[i, :] = list( map(float, outf[j + i + 1].split(":")[1].split())) # [bohr] if np.allclose(fp_lat, np.zeros((3, 3))): sys.exit("(EE) The lattice vectors were not found in: " + fplo_filename) T = np.dot(np.linalg.inv(ppy_lat), fp_lat) if not np.allclose(np.dot(T.T, T), np.eye(3)): sys.exit("(EE) The basis transformation is wrong!") for i in np.arange(len(fplo_forces)): fplo_forces[i] = np.dot(T, np.array(fplo_forces[i])) # Calculate the drift_force (sum over all forces has to be zero) and # normalize the forces. drift_force = get_drift_forces(fplo_forces, fplo_filename, verbose) force_sets.append(np.array(fplo_forces) - drift_force) return force_sets
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, 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, 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
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 == '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 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, 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, 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