def parse_forces(natom, force_to_eVperA, distance_to_A, cutoff_pair_distance=None, force_filename="FORCES_FC3", disp_filename=None, is_fc2=False, log_level=0): disp_dataset = _get_type2_dataset(natom, filename=force_filename) if disp_dataset: # type2 if log_level: print("%d snapshots were found in %s." % (len(disp_dataset['displacements']), "FORCES_FC3")) if force_to_eVperA is not None: disp_dataset['forces'] *= force_to_eVperA if distance_to_A is not None: disp_dataset['displacements'] *= distance_to_A else: # type1 if log_level: print("Displacement dataset for %s is read from \"%s\"." % ("fc2" if is_fc2 else "fc3", disp_filename)) if is_fc2: disp_dataset = parse_disp_fc2_yaml(filename=disp_filename) else: disp_dataset = parse_disp_fc3_yaml(filename=disp_filename) if cutoff_pair_distance: if ('cutoff_distance' not in disp_dataset or 'cutoff_distance' in disp_dataset and cutoff_pair_distance < disp_dataset['cutoff_distance']): disp_dataset['cutoff_distance'] = cutoff_pair_distance if log_level: print("Cutoff-pair-distance: %f" % cutoff_pair_distance) if disp_dataset['natom'] != natom: msg = ("Number of atoms in supercell is not consistent with " "\"%s\"." % disp_filename) raise RuntimeError(msg) _convert_displacement_unit(disp_dataset, distance_to_A, is_fc2=is_fc2) if log_level: print("Sets of supercell forces are read from \"%s\"." % force_filename) sys.stdout.flush() # forces are stored in disp_dataset. if is_fc2: parse_FORCES_FC2(disp_dataset, filename=force_filename, unit_conversion_factor=force_to_eVperA) else: parse_FORCES_FC3(disp_dataset, filename=force_filename, unit_conversion_factor=force_to_eVperA) return disp_dataset
def _create_phono3py_fc3(phono3py, force_to_eVperA, distance_to_A, symmetrize_fc3r, symmetrize_fc2, input_filename, output_filename, is_compact_fc, cutoff_pair_distance, use_alm, alm_options, compression, log_level): if input_filename is None: filename = 'disp_fc3.yaml' else: filename = 'disp_fc3.' + input_filename + '.yaml' file_exists(filename, log_level) if log_level: print("Displacement dataset for fc3 is read from %s." % filename) disp_dataset = parse_disp_fc3_yaml(filename=filename) if cutoff_pair_distance: if ('cutoff_distance' not in disp_dataset or 'cutoff_distance' in disp_dataset and cutoff_pair_distance < disp_dataset['cutoff_distance']): disp_dataset['cutoff_distance'] = cutoff_pair_distance if log_level: print("Cutoff-pair-distance: %f" % cutoff_pair_distance) num_atom = phono3py.get_supercell().get_number_of_atoms() if disp_dataset['natom'] != num_atom: print("Number of atoms in supercell is not consistent with %s" % filename) if log_level: print_error() sys.exit(1) _convert_displacement_unit(disp_dataset, distance_to_A) file_exists("FORCES_FC3", log_level) if log_level: print("Sets of supercell forces are read from %s." % "FORCES_FC3") sys.stdout.flush() forces_fc3 = parse_FORCES_FC3(disp_dataset) _convert_force_unit(forces_fc3, force_to_eVperA) phono3py.produce_fc3(forces_fc3, displacement_dataset=disp_dataset, symmetrize_fc3r=symmetrize_fc3r, is_compact_fc=is_compact_fc, use_alm=use_alm, alm_options=alm_options) if output_filename is None: filename = 'fc3.hdf5' else: filename = 'fc3.' + output_filename + '.hdf5' if log_level: print("Writing fc3 to %s" % filename) p2s_map = phono3py.get_primitive().get_primitive_to_supercell_map() write_fc3_to_hdf5(phono3py.get_fc3(), filename=filename, p2s_map=p2s_map, compression=compression) return True
def _create_phono3py_fc3(phono3py, force_to_eVperA, distance_to_A, tsym_type, symmetrize_fc3_r, symmetrize_fc2, cutoff_distance, input_filename, output_filename, use_alm, log_level): if input_filename is None: filename = 'disp_fc3.yaml' else: filename = 'disp_fc3.' + input_filename + '.yaml' file_exists(filename, log_level) if log_level: print("Displacement dataset is read from %s." % filename) disp_dataset = parse_disp_fc3_yaml(filename=filename) num_atom = phono3py.get_supercell().get_number_of_atoms() if disp_dataset['natom'] != num_atom: print("Number of atoms in supercell is not consistent with %s" % filename) if log_level: print_error() sys.exit(1) _convert_displacement_unit(disp_dataset, distance_to_A) file_exists("FORCES_FC3", log_level) if log_level: print("Sets of supercell forces are read from %s." % "FORCES_FC3") forces_fc3 = parse_FORCES_FC3(disp_dataset) if not forces_fc3: return False _convert_force_unit(forces_fc3, force_to_eVperA) phono3py.produce_fc3( forces_fc3, displacement_dataset=disp_dataset, cutoff_distance=cutoff_distance, translational_symmetry_type=tsym_type, is_permutation_symmetry=symmetrize_fc3_r, is_permutation_symmetry_fc2=symmetrize_fc2, use_alm=use_alm) if output_filename is None: filename = 'fc3.hdf5' else: filename = 'fc3.' + output_filename + '.hdf5' if log_level: print("Writing fc3 to %s" % filename) write_fc3_to_hdf5(phono3py.get_fc3(), filename=filename) return True
def create_supercells_with_displacements(phono3py): phono3py.generate_displacements(distance=0.03) scells_with_disps = phono3py.get_supercells_with_displacements() # from phonopy.interface.vasp import write_vasp # for i, scell in enumerate(scells_with_disps): # write_vasp("POSCAR-%05d" % (i + 1), scell) # # print(scell) # A dataset of displacements. The dictionary format is shown at # phono3py.phonon3.displacement_fc3.get_third_order_displacements. print("Displacement sets") disp_dataset = phono3py.get_displacement_dataset() count = 0 for i, disp1 in enumerate(disp_dataset['first_atoms']): print("%4d: %4d %s" % ( count + 1, disp1['number'] + 1, np.around(disp1['displacement'], decimals=3))) count += 1 distances = [] for i, disp1 in enumerate(disp_dataset['first_atoms']): for j, disp2 in enumerate(disp1['second_atoms']): print("%4d: %4d-%4d (%6.3f) %s %s" % ( count + 1, disp1['number'] + 1, disp2['number'] + 1, disp2['pair_distance'], np.around(disp1['displacement'], decimals=3), np.around(disp2['displacement'], decimals=3))) distances.append(disp2['pair_distance']) count += 1 # Find unique pair distances distances = np.array(distances) distances_int = (distances * 1e5).astype(int) unique_distances = np.unique(distances_int) * 1e-5 # up to 5 decimals print("Unique pair distances") print(unique_distances) # FORCES_FC3 is created as follows: from phono3py.file_IO import write_FORCES_FC3 # force_sets is a simple force array: # [len(scells_with_disps), num_supercell_atoms, 3]. force_sets = parse_FORCES_FC3(disp_dataset, filename="FORCES_FC3") write_FORCES_FC3(disp_dataset, force_sets, filename="FORCES_FC3_new")
def run_thermal_conductivity(phono3py): # Create fc3 and fc2 from disp_fc3.yaml and FORCES_FC3 disp_dataset = parse_disp_fc3_yaml(filename="disp_fc3.yaml") forces_fc3 = parse_FORCES_FC3(disp_dataset, filename="FORCES_FC3") phono3py.produce_fc3(forces_fc3, displacement_dataset=disp_dataset, is_translational_symmetry=True, is_permutation_symmetry=True, is_permutation_symmetry_fc2=True) fc3 = phono3py.get_fc3() fc2 = phono3py.get_fc2() # # Create fc2 from disp_fc2.yaml and FORCES_FC2 # disp_dataset2 = parse_disp_fc2_yaml(filename="disp_fc2.yaml") # forces_fc2 = parse_FORCES_FC2(disp_dataset2, filename="FORCES_FC2") # phono3py.produce_fc2( # forces_fc2, # displacement_dataset=disp_dataset2, # is_translational_symmetry=True, # is_permutation_symmetry=True) # # Read fc3 and fc2 from c3.hdf5 and fc2.hdf5 # fc3 = read_fc3_from_hdf5(filename="fc3.hdf5") # fc2 = read_fc2_from_hdf5(filename="fc2.hdf5") # phono3py.set_fc3(fc3) # phono3py.set_fc2(fc2) show_drift_fc3(fc3) show_drift_force_constants(fc2, name='fc2') # # For special cases like NAC # primitive = phono3py.get_phonon_primitive() # nac_params = parse_BORN(primitive, filename="BORN") # nac_params['factor'] = Hartree * Bohr # phono3py.set_phph_interaction(nac_params=nac_params) phono3py.run_thermal_conductivity( temperatures=range(0, 1001, 10), boundary_mfp=1e6, # This is to avoid divergence of phonon life time. write_kappa=True) # Conductivity_RTA object (https://git.io/vVRUW) cond_rta = phono3py.get_thermal_conductivity()
def create_supercells_with_displacements(phono3py): phono3py.generate_displacements(distance=0.03) scells_with_disps = phono3py.get_supercells_with_displacements() print(len(scells_with_disps)) # from phonopy.interface.vasp import write_vasp # for i, scell in enumerate(scells_with_disps): # write_vasp("POSCAR-%05d" % (i + 1), scell) # # print(scell) # A dataset of displacements. The dictionary format is shown at # phono3py.phonon3.displacement_fc3.get_third_order_displacements. disp_dataset = phono3py.get_displacement_dataset() # FORCES_FC3 is created as follows: from phono3py.file_IO import write_FORCES_FC3 # force_sets is a simple force array: # [len(scells_with_disps), num_supercell_atoms, 3]. force_sets = parse_FORCES_FC3(disp_dataset, filename="FORCES_FC3") write_FORCES_FC3(disp_dataset, force_sets, filename="FORCES_FC3_new")
def parse_forces( phono3py, ph3py_yaml=None, cutoff_pair_distance=None, force_filename="FORCES_FC3", disp_filename=None, fc_type=None, log_level=0, ): """Read displacements and forces.""" filename_read_from = None if fc_type == "phonon_fc2": natom = len(phono3py.phonon_supercell) else: natom = len(phono3py.supercell) # Get dataset from ph3py_yaml. dataset can be None. dataset = _extract_datast_from_ph3py_yaml(ph3py_yaml, fc_type) if dataset: filename_read_from = ph3py_yaml.yaml_filename # Try to read FORCES_FC* if type-2 and return dataset. # None is returned unless type-2. # can emit FileNotFoundError. if dataset is None or dataset is not None and not forces_in_dataset( dataset): _dataset = _get_type2_dataset(natom, phono3py.calculator, filename=force_filename, log_level=log_level) # Do not overwrite dataset when _dataset is None. if _dataset: filename_read_from = force_filename dataset = _dataset if dataset is None: # Displacement dataset is obtained from disp_filename. # can emit FileNotFoundError. dataset = _read_disp_fc_yaml(disp_filename, fc_type) filename_read_from = disp_filename if "natom" in dataset and dataset["natom"] != natom: msg = ("Number of atoms in supercell is not consistent with " '"%s".' % filename_read_from) raise RuntimeError(msg) if log_level and filename_read_from is not None: print('Displacement dataset for %s was read from "%s".' % (fc_type, filename_read_from)) # Overwrite dataset['cutoff_distance'] when necessary. if cutoff_pair_distance: if "cutoff_distance" not in dataset or ( "cutoff_distance" in dataset and cutoff_pair_distance < dataset["cutoff_distance"]): dataset["cutoff_distance"] = cutoff_pair_distance if log_level: print("Cutoff-pair-distance: %f" % cutoff_pair_distance) # Type-1 FORCES_FC*. # dataset comes either from disp_fc*.yaml or phono3py*.yaml. if not forces_in_dataset(dataset): if fc_type == "phonon_fc2": parse_FORCES_FC2(dataset, filename=force_filename) else: parse_FORCES_FC3(dataset, filename=force_filename) if log_level: print('Sets of supercell forces were read from "%s".' % force_filename) sys.stdout.flush() _convert_unit_in_dataset(dataset, phono3py.calculator) return dataset
def _create_phono3py_fc3(phono3py, force_to_eVperA, distance_to_A, symmetrize_fc3r, symmetrize_fc2, input_filename, output_filename, is_compact_fc, cutoff_pair_distance, fc_calculator, fc_calculator_options, compression, log_level): file_exists("FORCES_FC3", log_level) natom = phono3py.supercell.get_number_of_atoms() disp_dataset = _get_type2_dataset(natom, filename="FORCES_FC3") if disp_dataset: # type2 if log_level: print("%d snapshots were found in %s." % (len(disp_dataset['displacements']), "FORCES_FC3")) if force_to_eVperA is not None: disp_dataset['forces'] *= force_to_eVperA if distance_to_A is not None: disp_dataset['displacements'] *= distance_to_A else: # type1 if input_filename is None: filename = 'disp_fc3.yaml' else: filename = 'disp_fc3.' + input_filename + '.yaml' file_exists(filename, log_level) if log_level: print("Displacement dataset for fc3 is read from %s." % filename) disp_dataset = parse_disp_fc3_yaml(filename=filename) if cutoff_pair_distance: if ('cutoff_distance' not in disp_dataset or 'cutoff_distance' in disp_dataset and cutoff_pair_distance < disp_dataset['cutoff_distance']): disp_dataset['cutoff_distance'] = cutoff_pair_distance if log_level: print("Cutoff-pair-distance: %f" % cutoff_pair_distance) num_atom = phono3py.get_supercell().get_number_of_atoms() if disp_dataset['natom'] != num_atom: print("Number of atoms in supercell is not consistent with %s" % filename) if log_level: print_error() sys.exit(1) _convert_displacement_unit(disp_dataset, distance_to_A) if log_level: print("Sets of supercell forces are read from %s." % "FORCES_FC3") sys.stdout.flush() # forces are stored in disp_dataset. parse_FORCES_FC3(disp_dataset, unit_conversion_factor=force_to_eVperA) phono3py.produce_fc3(displacement_dataset=disp_dataset, symmetrize_fc3r=symmetrize_fc3r, is_compact_fc=is_compact_fc, fc_calculator=fc_calculator, fc_calculator_options=fc_calculator_options) if output_filename is None: filename = 'fc3.hdf5' else: filename = 'fc3.' + output_filename + '.hdf5' if log_level: print("Writing fc3 to %s" % filename) write_fc3_to_hdf5(phono3py.get_fc3(), filename=filename, p2s_map=phono3py.primitive.p2s_map, compression=compression) return True