def test_kappa_RTA_si_nomeshsym(si_pbesol: Phono3py, si_pbesol_nomeshsym: Phono3py): """Test RTA without considering mesh symmetry by Si.""" si_pbesol_nomeshsym.fc2 = si_pbesol.fc2 si_pbesol_nomeshsym.fc3 = si_pbesol.fc3 kappa = _get_kappa(si_pbesol_nomeshsym, [7, 7, 7]).ravel() kappa_ref = si_pbesol_kappa_RTA_si_nomeshsym np.testing.assert_allclose(kappa_ref, kappa, atol=0.5)
def _set_forces_fc3( ph3py: Phono3py, ph3py_yaml: typing.Union[Phono3pyYaml, None], force_filename, disp_filename, produce_fc, symmetrize_fc, is_compact_fc, fc_calculator, fc_calculator_options, cutoff_pair_distance, log_level, ): ph3py.dataset = parse_forces( ph3py, ph3py_yaml=ph3py_yaml, cutoff_pair_distance=cutoff_pair_distance, force_filename=force_filename, disp_filename=disp_filename, fc_type="fc3", log_level=log_level, ) if produce_fc: ph3py.produce_fc3( symmetrize_fc3r=symmetrize_fc, is_compact_fc=is_compact_fc, fc_calculator=fc_calculator, fc_calculator_options=fc_calculator_options, ) if log_level and symmetrize_fc: print("fc3 was symmetrized.")
def _set_forces_fc2( ph3py: Phono3py, ph3py_yaml: typing.Union[Phono3pyYaml, None], force_filename, disp_filename, produce_fc, symmetrize_fc, is_compact_fc, fc_calculator, fc_calculator_options, fc_type, log_level, ): dataset = parse_forces( ph3py, ph3py_yaml=ph3py_yaml, force_filename=force_filename, disp_filename=disp_filename, fc_type=fc_type, log_level=log_level, ) if fc_type == "phonon_fc2": ph3py.phonon_dataset = dataset else: ph3py.dataset = dataset if produce_fc: ph3py.produce_fc2( symmetrize_fc2=symmetrize_fc, is_compact_fc=is_compact_fc, fc_calculator=fc_calculator, fc_calculator_options=fc_calculator_options, ) if log_level and symmetrize_fc: print("fc2 was symmetrized.")
def test_real_self_energy_with_frequency_points(si_pbesol: Phono3py): """Real part of self energy spectrum of Si. * specified frquency points """ si_pbesol.mesh_numbers = [9, 9, 9] si_pbesol.init_phph_interaction() frequency_points = [1.469947, 3.085309, 14.997187, 15.129080] fps, delta = si_pbesol.run_real_self_energy( si_pbesol.grid.grg2bzg[[1, 103]], [ 300, ], frequency_points=frequency_points, write_hdf5=False, frequency_points_at_bands=False, ) np.testing.assert_allclose(frequency_points, fps, atol=1e-5) np.testing.assert_allclose(si_pbesol_Delta_fps[0], delta[0, 0, 0].ravel(), atol=0.01) np.testing.assert_allclose(si_pbesol_Delta_fps[1], delta[0, 0, 1].ravel(), atol=0.01)
def test_SpectralFunction_band_indices(si_pbesol: Phono3py): """Spectral function of Si.""" si_pbesol.mesh_numbers = [9, 9, 9] si_pbesol.band_indices = [[4, 5]] si_pbesol.init_phph_interaction() sf = SpectralFunction( si_pbesol.phph_interaction, si_pbesol.grid.grg2bzg[[1, 103]], temperatures=[ 300, ], num_frequency_points=10, log_level=1, ) sf.run() # for line in np.swapaxes(sf.spectral_functions, -2, -1).reshape(-1, 6): # print(("%.7f, " * 6) % tuple(line)) # raise np.testing.assert_allclose( np.reshape(shifts, (-1, 6))[:, [4, 5]], np.swapaxes(sf.shifts, -2, -1).reshape(-1, 2), atol=1e-2, ) np.testing.assert_allclose( np.reshape(spec_funcs, (-1, 6))[:, [4, 5]], np.swapaxes(sf.spectral_functions, -2, -1).reshape(-1, 2), atol=1e-2, rtol=1e-2, )
def create_supercells_with_displacements(): """Create supercells with displacements.""" cell = read_vasp("POSCAR-unitcell") ph3 = Phono3py(cell, np.diag([2, 2, 2]), primitive_matrix="F") ph3.generate_displacements(distance=0.03) print(ph3.supercells_with_displacements) # List of PhonopyAtoms print(ph3.displacements.shape) # (supercells, atoms, xyz)
def _calculate_kappados(ph3: Phono3py, mode_prop, freq_points=None): tc = ph3.thermal_conductivity bz_grid = ph3.grid frequencies, _, _ = ph3.get_phonon_data() kappados = KappaDOS(mode_prop, frequencies, bz_grid, tc.grid_points, frequency_points=freq_points) freq_points, kdos = kappados.get_kdos() ir_grid_points, _, ir_grid_map = get_ir_grid_points(bz_grid) kappados = KappaDOS( mode_prop, tc.frequencies, bz_grid, tc.grid_points, ir_grid_map=ir_grid_map, frequency_points=freq_points, ) ir_freq_points, ir_kdos = kappados.get_kdos() np.testing.assert_equal(bz_grid.bzg2grg[tc.grid_points], ir_grid_points) np.testing.assert_allclose(ir_freq_points, freq_points, rtol=0, atol=1e-5) np.testing.assert_allclose(ir_kdos, kdos, rtol=0, atol=1e-5) return freq_points, kdos[0, :, :, 0]
def test_jdos_nacl_nac_gamma_at_300K_npoints(nacl_pbe: Phono3py): """Real part of self energy spectrum of NaCl. * at 10 frequency points sampled uniformly. * at q->0 """ nacl_pbe.mesh_numbers = [9, 9, 9] jdos = Phono3pyJointDos( nacl_pbe.phonon_supercell, nacl_pbe.phonon_primitive, nacl_pbe.fc2, mesh=nacl_pbe.mesh_numbers, nac_params=nacl_pbe.nac_params, nac_q_direction=[1, 0, 0], num_frequency_points=10, temperatures=[ 300, ], log_level=1, ) jdos.run([nacl_pbe.grid.gp_Gamma]) # print(", ".join(["%.7f" % fp for fp in jdos.frequency_points])) np.testing.assert_allclose(nacl_freq_points_gamma_at_300K, jdos.frequency_points, atol=1e-5) # print(", ".join(["%.7f" % jd for jd in jdos.joint_dos.ravel()])) np.testing.assert_allclose(nacl_jdos_gamma_at_300K[2:], jdos.joint_dos.ravel()[2:], rtol=1e-2, atol=1e-5)
def test_jdos_nacl_at_300K(nacl_pbe: Phono3py, gp: int, store_dense_gp_map: bool): """Test joint-DOS at 300K by NaCl.""" nacl_pbe.mesh_numbers = [9, 9, 9] jdos = Phono3pyJointDos( nacl_pbe.phonon_supercell, nacl_pbe.phonon_primitive, nacl_pbe.fc2, mesh=nacl_pbe.mesh_numbers, nac_params=nacl_pbe.nac_params, num_frequency_points=10, temperatures=[ 300, ], store_dense_gp_map=store_dense_gp_map, log_level=1, ) jdos.run([gp]) # print(", ".join(["%.7f" % fp for fp in jdos.frequency_points])) np.testing.assert_allclose(nacl_freq_points_at_300K, jdos.frequency_points, atol=1e-5) # print(", ".join(["%.7f" % jd for jd in jdos.joint_dos.ravel()])) np.testing.assert_allclose(nacl_jdos_12_at_300K[2:], jdos.joint_dos.ravel()[2:], rtol=1e-2, atol=1e-5)
def test_jdos_si(si_pbesol: Phono3py, gp: int, store_dense_gp_map: bool): """Test joint-DOS by Si. store_dense_gp_map=False : 103 store_dense_gp_map=True : 105 """ si_pbesol.mesh_numbers = [9, 9, 9] jdos = Phono3pyJointDos( si_pbesol.phonon_supercell, si_pbesol.phonon_primitive, si_pbesol.fc2, mesh=si_pbesol.mesh_numbers, num_frequency_points=10, store_dense_gp_map=store_dense_gp_map, log_level=1, ) jdos.run([gp]) # print(", ".join(["%.7f" % fp for fp in jdos.frequency_points])) np.testing.assert_allclose(si_freq_points, jdos.frequency_points, atol=1e-5) # print(", ".join(["%.7f" % jd for jd in jdos.joint_dos.ravel()])) np.testing.assert_allclose(si_jdos_12[2:], jdos.joint_dos.ravel()[2:], rtol=1e-2, atol=1e-5)
def _get_irt(ph3: Phono3py, mesh, nac_params=None, solve_dynamical_matrices=True): ph3.mesh_numbers = mesh itr = Interaction(ph3.primitive, ph3.grid, ph3.primitive_symmetry, ph3.fc3, cutoff_frequency=1e-4) if nac_params is None: itr.init_dynamical_matrix( ph3.fc2, ph3.phonon_supercell, ph3.phonon_primitive, ) else: itr.init_dynamical_matrix( ph3.fc2, ph3.phonon_supercell, ph3.phonon_primitive, nac_params=nac_params, ) if solve_dynamical_matrices: itr.run_phonon_solver() return itr
def init_phono3py(settings, cell_info, interface_mode, output_filename, symprec, log_level): physical_units = get_default_physical_units(interface_mode) distance_to_A = physical_units['distance_to_A'] # Change unit of lattice parameters to angstrom unitcell = cell_info['unitcell'].copy() if distance_to_A is not None: lattice = unitcell.cell lattice *= distance_to_A unitcell.cell = lattice # updated_settings keys # ('grid_points', 'sigmas', 'temperature_points', 'temperatures', # 'frequency_factor_to_THz', 'num_frequency_points', # 'frequency_step', 'frequency_scale_factor', # 'cutoff_frequency') updated_settings = get_default_values(settings) phono3py = Phono3py( unitcell, cell_info['supercell_matrix'], primitive_matrix=cell_info['primitive_matrix'], phonon_supercell_matrix=cell_info['phonon_supercell_matrix'], masses=settings.masses, mesh=settings.mesh_numbers, band_indices=settings.band_indices, sigmas=updated_settings['sigmas'], sigma_cutoff=settings.sigma_cutoff_width, cutoff_frequency=updated_settings['cutoff_frequency'], frequency_factor_to_THz=updated_settings['frequency_factor_to_THz'], is_symmetry=settings.is_symmetry, is_mesh_symmetry=settings.is_mesh_symmetry, symmetrize_fc3q=settings.is_symmetrize_fc3_q, symprec=symprec, calculator=interface_mode, log_level=log_level, lapack_zheev_uplo=settings.lapack_zheev_uplo) check_supercell_in_yaml(cell_info, phono3py, log_level) if cell_info['phonopy_yaml'] is not None: if (cell_info['phonopy_yaml'].phonon_supercell is not None and phono3py.phonon_supercell is not None): if not cells_isclose(cell_info['phonopy_yaml'].phonon_supercell, phono3py.phonon_supercell): if log_level: print("Generated phonon supercell is inconsistent with " "that in \"%s\"." % cell_info['optional_structure_info'][0]) print_error() sys.exit(1) return phono3py, updated_settings
def _get_phono3pyobject_phono3py(self, structure, potential, kpoint_density, displacementdistancephono3py, max_distance_third_order): cell = get_phonopy_structure(structure) kpoint = Kpoints.automatic_density(structure=structure, kppa=kpoint_density, force_gamma=True) mesh = kpoint.kpts[0] phono3py = Phono3py(cell, self.smat, primitive_matrix=[[1, 0., 0.], [0., 1, 0.], [0., 0., 1]], mesh=mesh, log_level=1) phono3py.generate_displacements( distance=displacementdistancephono3py, cutoff_pair_distance=max_distance_third_order) scells_with_disps = phono3py.get_supercells_with_displacements() disp_dataset = phono3py.get_displacement_dataset() numatoms = len(scells_with_disps[0].get_scaled_positions()) dummy_force = np.zeros((numatoms, 3)) set_of_forces = [] for scell in scells_with_disps: if scell is not None: # this part is adapted from: https://web.archive.org/web/20200610084959/https://github.com/phonopy/phonopy/blob/develop/example/ase/8Si-phonon.py # Copyright by Atsushi Togo cell = Atoms(symbols=scell.get_chemical_symbols(), scaled_positions=scell.get_scaled_positions(), cell=scell.get_cell(), pbc=True) cell.set_calculator(potential) forces = cell.get_forces() drift_force = forces.sum(axis=0) print(("[Phonopy] Drift force:" + "%11.5f" * 3) % tuple(drift_force)) for force in forces: force -= drift_force / forces.shape[0] set_of_forces.append(forces) else: set_of_forces.append(dummy_force) phono3py.produce_fc3(set_of_forces, displacement_dataset=disp_dataset, symmetrize_fc3r=True) fc3 = phono3py.get_fc3() show_drift_fc3(fc3) return phono3py
def test_real_self_energy_nacl_nac_npoints(nacl_pbe: Phono3py): """Real part of self energy spectrum of NaCl. * at 10 frequency points sampled uniformly. * at q->0 """ nacl_pbe.mesh_numbers = [9, 9, 9] nacl_pbe.init_phph_interaction(nac_q_direction=[1, 0, 0]) fps, delta = nacl_pbe.run_real_self_energy([nacl_pbe.grid.gp_Gamma], [300], num_frequency_points=10) # for line in np.swapaxes(delta, -1, -2).ravel().reshape(-1, 6): # print(("%10.8f, " * 6) % tuple(line)) # print(fps.ravel()) np.testing.assert_allclose(freq_points_nacl_nac, fps.ravel(), rtol=0, atol=1e-5) np.testing.assert_allclose(delta_nacl_nac, np.swapaxes(delta, -1, -2).ravel(), rtol=0, atol=1e-2)
def init_phono3py(settings, cell_info, interface_mode, symprec, log_level): """Initialize phono3py and update settings by default values.""" physical_units = get_default_physical_units(interface_mode) distance_to_A = physical_units["distance_to_A"] # Change unit of lattice parameters to angstrom unitcell = cell_info["unitcell"].copy() if distance_to_A is not None: lattice = unitcell.cell lattice *= distance_to_A unitcell.cell = lattice # updated_settings keys # ('sigmas', 'temperature_points', 'temperatures', # 'frequency_factor_to_THz', 'num_frequency_points', # 'frequency_step', 'frequency_scale_factor', # 'cutoff_frequency') updated_settings = get_default_values(settings) phono3py = Phono3py( unitcell, cell_info["supercell_matrix"], primitive_matrix=cell_info["primitive_matrix"], phonon_supercell_matrix=cell_info["phonon_supercell_matrix"], cutoff_frequency=updated_settings["cutoff_frequency"], frequency_factor_to_THz=updated_settings["frequency_factor_to_THz"], is_symmetry=settings.is_symmetry, is_mesh_symmetry=settings.is_mesh_symmetry, use_grg=settings.use_grg, store_dense_gp_map=(not settings.emulate_v1), store_dense_svecs=(not settings.emulate_v1), symprec=symprec, calculator=interface_mode, log_level=log_level, ) phono3py.masses = settings.masses phono3py.band_indices = settings.band_indices phono3py.sigmas = updated_settings["sigmas"] phono3py.sigma_cutoff = settings.sigma_cutoff_width check_supercell_in_yaml(cell_info, phono3py, distance_to_A, log_level) return phono3py, updated_settings
def get_phono3py_instance(structure, phonon_settings_dict, params): from phono3py import Phono3py if 'phonon_supercell_matrix' in phonon_settings_dict: ph_smat = phonon_settings_dict['phonon_supercell_matrix'] else: ph_smat = None ph3py = Phono3py(phonopy_atoms_from_structure(structure), supercell_matrix=phonon_settings_dict['supercell_matrix'], primitive_matrix='auto', phonon_supercell_matrix=ph_smat, symprec=phonon_settings_dict['symmetry_tolerance']) if 'nac_params' in params: from phonopy.interface.calculator import get_default_physical_units units = get_default_physical_units('vasp') factor = units['nac_factor'] nac_params = { 'born': params['nac_params'].get_array('born_charges'), 'dielectric': params['nac_params'].get_array('epsilon'), 'factor': factor } ph3py.nac_params = nac_params return ph3py
if __name__ == '__main__': infile = 'geometry.unitcell.in' supercell_matrix = np.diag([4, 4, 1]) mesh = [21, 21, 1] temperatures = [80] symprec = 1e-5 cutoff_pair_distance = 6.0 print("cutoff_pair_distance: %.2f" % cutoff_pair_distance) atoms = read(infile, format='aims') print("Cell:") print(atoms.get_cell()[:]) cell = to_phonopy_atoms(atoms, wrap=False) phono3py = Phono3py(unitcell=cell, supercell_matrix=supercell_matrix, mesh=mesh, symprec=symprec, log_level=2) # log_level=0 make phono3py quiet print("Cell symmetry by international table: %s" % phono3py._symmetry._international_table) print("Supercell symmetry by international table: %s" % phono3py._phonon_supercell_symmetry._international_table) print("Symmetry precision %g" % symprec) print("Primitive cell:") print(phono3py._primitive) # sys.exit(0) create_supercells_with_displacements( phono3py, cutoff_pair_distance=cutoff_pair_distance)
def init_phph_interaction( phono3py: Phono3py, settings, updated_settings, input_filename, output_filename, log_level, ): """Initialize ph-ph interaction and phonons on grid.""" if log_level: print("Generating grid system ... ", end="", flush=True) phono3py.mesh_numbers = settings.mesh_numbers bz_grid = phono3py.grid if log_level: if bz_grid.grid_matrix is None: print("[ %d %d %d ]" % tuple(phono3py.mesh_numbers)) else: print("") print("Generalized regular grid: [ %d %d %d ]" % tuple(bz_grid.D_diag)) print("Grid generation matrix:") print(" [ %d %d %d ]" % tuple(bz_grid.grid_matrix[0])) print(" [ %d %d %d ]" % tuple(bz_grid.grid_matrix[1])) print(" [ %d %d %d ]" % tuple(bz_grid.grid_matrix[2])) if settings.is_symmetrize_fc3_q: print("Permutation symmetry of ph-ph interaction strengths: True") ave_pp = settings.constant_averaged_pp_interaction phono3py.init_phph_interaction( nac_q_direction=settings.nac_q_direction, constant_averaged_interaction=ave_pp, frequency_scale_factor=updated_settings["frequency_scale_factor"], symmetrize_fc3q=settings.is_symmetrize_fc3_q, lapack_zheev_uplo=settings.lapack_zheev_uplo, ) if not settings.read_phonon: if log_level: print("-" * 27 + " Phonon calculations " + "-" * 28) dm = phono3py.dynamical_matrix if dm.is_nac() and dm.nac_method == "gonze": dm.show_nac_message() print("Running harmonic phonon calculations...") sys.stdout.flush() phono3py.run_phonon_solver() if settings.write_phonon: freqs, eigvecs, grid_address = phono3py.get_phonon_data() ir_grid_points, ir_grid_weights, _ = get_ir_grid_points(bz_grid) ir_grid_points = np.array(bz_grid.grg2bzg[ir_grid_points], dtype="int_") filename = write_phonon_to_hdf5( freqs, eigvecs, grid_address, phono3py.mesh_numbers, bz_grid=bz_grid, ir_grid_points=ir_grid_points, ir_grid_weights=ir_grid_weights, compression=settings.hdf5_compression, filename=output_filename, ) if filename: if log_level: print('Phonons are written into "%s".' % filename) else: print("Writing phonons failed.") if log_level: print_error() sys.exit(1) if settings.read_phonon: phonons = read_phonon_from_hdf5(phono3py.mesh_numbers, filename=input_filename, verbose=(log_level > 0)) if phonons is None: print("Reading phonons failed.") if log_level: print_error() sys.exit(1) try: phono3py.set_phonon_data(*phonons) except RuntimeError: if log_level: print_error() sys.exit(1)
from os import environ environ['CUDA_VISIBLE_DEVICES'] = '' from phonopy.interface import vasp atoms = vasp.read_vasp(unitcell_f) from phono3py import Phono3py pho = Phono3py( unitcell=atoms, supercell_matrix=NNN3, primitive_matrix=prim_mat, phonon_supercell_matrix=NNN2, # masses = None, # mesh = None, # band_indices = None, # sigmas = None, # sigma_cutoff = None, # cutoff_frequency = 1e-4, # frequency_factor_to_THz = VaspToTHz, # is_symmetry = True, # is_mesh_symmetry = True, symmetrize_fc3q=sym_fc, # symprec = 1e-5, # calculator = None, # log_level = 0, # lapack_zheev_uplo = 'L', ) if nac: pho.set_nac_params(nac_params) from ase.dft.kpoints import ibz_points points = ibz_points['hexagonal']
def create_phono3py_supercells(unitcell, supercell_matrix, phonon_supercell_matrix, displacement_distance, is_plusminus, is_diagonal, cutoff_pair_distance, optional_structure_info, is_symmetry, symprec, interface_mode='vasp', output_filename=None, log_level=1): if displacement_distance is None: distance = get_default_displacement_distance(interface_mode) else: distance = displacement_distance phono3py = Phono3py(unitcell, supercell_matrix, phonon_supercell_matrix=phonon_supercell_matrix, is_symmetry=is_symmetry, symprec=symprec) supercell = phono3py.get_supercell() phono3py.generate_displacements(distance=distance, cutoff_pair_distance=cutoff_pair_distance, is_plusminus=is_plusminus, is_diagonal=is_diagonal) dds = phono3py.get_displacement_dataset() if log_level: print('') print("Displacement distance: %s" % distance) if output_filename is None: filename = 'disp_fc3.yaml' else: filename = 'disp_fc3.' + output_filename + '.yaml' num_disps, num_disp_files = write_disp_fc3_yaml(dds, supercell, filename=filename) cells_with_disps = phono3py.supercells_with_displacements ids = [] disp_cells = [] for i, cell in enumerate(cells_with_disps): if cell is not None: ids.append(i + 1) disp_cells.append(cell) additional_info = get_additional_info_to_write_supercells( interface_mode, phono3py) write_supercells_with_displacements(interface_mode, supercell, disp_cells, optional_structure_info, displacement_ids=ids, zfill_width=5, additional_info=additional_info) if log_level: print("Number of displacements: %d" % num_disps) if cutoff_pair_distance is not None: print("Cutoff distance for displacements: %s" % cutoff_pair_distance) print("Number of displacement supercell files created: %d" % num_disp_files) if phonon_supercell_matrix is not None: phonon_dds = phono3py.phonon_dataset phonon_supercell = phono3py.phonon_supercell phonon_supercell_matrix = phono3py.phonon_supercell_matrix if output_filename is None: filename = 'disp_fc2.yaml' else: filename = 'disp_fc2.' + output_filename + '.yaml' num_disps = write_disp_fc2_yaml(phonon_dds, phonon_supercell, filename=filename) cells_with_disps = phono3py.phonon_supercells_with_displacements additional_info = get_additional_info_to_write_fc2_supercells( interface_mode, phono3py) write_supercells_with_displacements(interface_mode, supercell, cells_with_disps, optional_structure_info, zfill_width=5, additional_info=additional_info) if log_level: print("Number of displacements for special fc2: %d" % num_disps) return phono3py
def load( phono3py_yaml=None, # phono3py.yaml-like must be the first argument. supercell_matrix=None, primitive_matrix=None, phonon_supercell_matrix=None, mesh=None, is_nac=True, calculator=None, unitcell=None, supercell=None, nac_params=None, unitcell_filename=None, supercell_filename=None, born_filename=None, forces_fc3_filename=None, forces_fc2_filename=None, fc3_filename=None, fc2_filename=None, fc_calculator=None, factor=None, frequency_scale_factor=None, is_symmetry=True, is_mesh_symmetry=True, symprec=1e-5, log_level=0): """Create Phono3py instance from parameters and/or input files. When unitcell and unitcell_filename are not given, file name that is default for the chosen calculator is looked for in the current directory as the default behaviour. When force_sets_filename and force_constants_filename are not given, 'FORCES_FC3' and 'FORCES_FC2' are looked for in the current directory as the default behaviour. Parameters ---------- phono3py_yaml : str, optional Filename of "phono3py.yaml"-like file. If this is given, the data in the file are parsed. Default is None. supercell_matrix : array_like, optional Supercell matrix multiplied to input cell basis vectors. shape=(3, ) or (3, 3), where the former is considered a diagonal matrix. Default is the unit matrix. dtype=int primitive_matrix : array_like or str, optional Primitive matrix multiplied to input cell basis vectors. Default is the identity matrix. Default is None, which is equivalent to 'auto'. shape=(3, 3), dtype=float. When 'F', 'I', 'A', 'C', or 'R' is given instead of a 3x3 matrix, the primitive matrix defined at https://atztogo.github.io/spglib/definition.html is used. phonon_supercell_matrix : array_like, optional Supercell matrix used for fc2. In phono3py, supercell matrix for fc3 and fc2 can be different to support longer range interaction of fc2 than that of fc3. Unless setting this, supercell_matrix is used. This is only valide when unitcell or unitcell_filename is given. Default is None. mesh : array_like, optional Grid mesh numbers in reciprocal cell. shape=(3,), dtype='intc' is_nac : bool, optional If True, look for 'BORN' file. If False, NAS is turned off. The priority for NAC is nac_params > born_filename > is_nac ('BORN'). Default is True. calculator : str, optional. Calculator used for computing forces. This is used to switch the set of physical units. Default is None, which is equivalent to "vasp". unitcell : PhonopyAtoms, optional Input unit cell. Default is None. The priority for cell is unitcell_filename > supercell_filename > unitcell > supercell. supercell : PhonopyAtoms, optional Input supercell. Default value of primitive_matrix is set to 'auto' (can be overwitten). supercell_matrix is ignored. Default is None. The priority for cell is unitcell_filename > supercell_filename > unitcell > supercell. nac_params : dict, optional Parameters required for non-analytical term correction. Default is None. The priority for NAC is nac_params > born_filename > is_nac. {'born': Born effective charges (array_like, shape=(primitive cell atoms, 3, 3), dtype=float), 'dielectric': Dielectric constant matrix (array_like, shape=(3, 3), dtype=float), 'factor': unit conversion facotr (float)} unitcell_filename : str, optional Input unit cell filename. Default is None. The priority for cell is unitcell_filename > supercell_filename > unitcell > supercell. supercell_filename : str, optional Input supercell filename. When this is specified, supercell_matrix is ignored. Default is None. The priority for cell is 1. unitcell_filename (with supercell_matrix) 2. supercell_filename 3. unitcell (with supercell_matrix) 4. supercell. born_filename : str, optional Filename corresponding to 'BORN', a file contains non-analytical term correction parameters. The priority for NAC is nac_params > born_filename > is_nac ('BORN'). forces_fc3_filename : str, optional Filename of a file corresponding to 'FORCES_FC3', a file contains sets of forces or optionally displacements (type-2). Default is None. The priority for force constants is fc3_filename > forces_fc3_filename > 'fc3.hdf5' > 'FORCES_FC3'. forces_fc2_filename : str, optional Filename of a file corresponding to 'FORCES_FC2', a file contains sets of forces or optionally displacements (type-2). Default is None. The priority for force constants is fc2_filename > forces_fc2_filename > 'fc2.hdf5' > 'FORCES_FC2'. fc3_filename : str, optional Filename of a file corresponding to 'fc3.hdf5', a file contains third-order force constants. Default is None. The priority for force constants is fc3_filename > forces_fc3_filename > 'fc3.hdf5' > 'FORCES_FC3'. fc2_filename : str, optional Filename of a file corresponding to 'fc2.hdf5', a file contains second-order force constants. Default is None. The priority for force constants is fc2_filename > forces_fc2_filename > 'fc2.hdf5' > 'FORCES_FC2'. fc_calculator : str, optional Force constants calculator. Currently only 'alm'. Default is None. factor : float, optional Phonon frequency unit conversion factor. Unless specified, default unit conversion factor for each calculator is used. frequency_scale_factor : float, optional Factor multiplied to calculated phonon frequency. Default is None, i.e., effectively 1. is_symmetry : bool, optional Setting False, crystal symmetry except for lattice translation is not considered. Default is True. is_mesh_symmetry : bool, optional Setting False, reciprocal mesh symmetry is not considered. Default is True. symprec : float, optional Tolerance used to find crystal symmetry. Default is 1e-5. log_level : int, optional Verbosity control. Default is 0. """ if phono3py_yaml is None: cell, smat, pmat = load_helper.get_cell_settings( supercell_matrix=supercell_matrix, primitive_matrix=primitive_matrix, unitcell=unitcell, supercell=supercell, unitcell_filename=unitcell_filename, supercell_filename=supercell_filename, calculator=calculator, symprec=symprec) if phonon_supercell_matrix is not None: if unitcell is None and unitcell_filename is None: msg = ("phonon_supercell_matrix can be used only when " "unitcell or unitcell_filename is given.") raise RuntimeError(msg) ph_smat = load_helper.get_supercell_matrix(phonon_supercell_matrix) else: ph_smat = None _nac_params = nac_params else: ph3py_yaml = Phono3pyYaml() ph3py_yaml.read(phono3py_yaml) cell = ph3py_yaml.unitcell smat = ph3py_yaml.supercell_matrix ph_smat = ph3py_yaml.phonon_supercell_matrix if smat is None: smat = np.eye(3, dtype='intc', order='C') if primitive_matrix == 'auto': pmat = 'auto' else: pmat = ph3py_yaml.primitive_matrix if is_nac: _nac_params = ph3py_yaml.nac_params else: _nac_params = None # units keywords: factor, nac_factor, distance_to_A units = get_default_physical_units(calculator) if factor is None: _factor = units['factor'] else: _factor = factor ph3py = Phono3py(cell, smat, primitive_matrix=pmat, phonon_supercell_matrix=ph_smat, mesh=mesh, frequency_factor_to_THz=_factor, symprec=symprec, is_symmetry=is_symmetry, is_mesh_symmetry=is_mesh_symmetry, calculator=calculator, log_level=log_level) _nac_params = load_helper.get_nac_params(ph3py.primitive, _nac_params, born_filename, is_nac, units['nac_factor']) _set_force_constants(ph3py, dataset=None, fc3_filename=fc3_filename, fc2_filename=fc2_filename, forces_fc3_filename=forces_fc3_filename, forces_fc2_filename=forces_fc2_filename, fc_calculator=fc_calculator) if mesh is not None: ph3py.set_phph_interaction( nac_params=_nac_params, frequency_scale_factor=frequency_scale_factor) return ph3py
def create_phono3py_supercells(cell_info, settings, symprec, output_filename=None, interface_mode='vasp', log_level=1): """create displacements and supercells Distance unit used is that for the calculator interface. The default unit is Angstron. """ optional_structure_info = cell_info['optional_structure_info'] if settings.displacement_distance is None: distance = get_default_displacement_distance(interface_mode) else: distance = settings.displacement_distance phono3py = Phono3py( cell_info['unitcell'], cell_info['supercell_matrix'], primitive_matrix=cell_info['primitive_matrix'], phonon_supercell_matrix=cell_info['phonon_supercell_matrix'], is_symmetry=settings.is_symmetry, symprec=symprec, calculator=interface_mode) phono3py.generate_displacements( distance=distance, cutoff_pair_distance=settings.cutoff_pair_distance, is_plusminus=settings.is_plusminus_displacement, is_diagonal=settings.is_diagonal_displacement) if log_level: print('') print("Unit cell was read from \"%s\"." % optional_structure_info[0]) print("Displacement distance: %s" % distance) if output_filename is None: filename = 'disp_fc3.yaml' else: filename = 'disp_fc3.' + output_filename + '.yaml' num_disps, num_disp_files = write_disp_fc3_yaml(phono3py.dataset, phono3py.supercell, filename=filename) ids = [] disp_cells = [] for i, cell in enumerate(phono3py.supercells_with_displacements): if cell is not None: ids.append(i + 1) disp_cells.append(cell) additional_info = get_additional_info_to_write_supercells( interface_mode, phono3py.supercell_matrix) write_supercells_with_displacements(interface_mode, phono3py.supercell, disp_cells, optional_structure_info, displacement_ids=ids, zfill_width=5, additional_info=additional_info) if log_level: print("Number of displacements: %d" % num_disps) if settings.cutoff_pair_distance is not None: print("Cutoff distance for displacements: %s" % settings.cutoff_pair_distance) print("Number of displacement supercell files created: %d" % num_disp_files) if phono3py.phonon_supercell_matrix is not None: if output_filename is None: filename = 'disp_fc2.yaml' else: filename = 'disp_fc2.' + output_filename + '.yaml' num_disps = write_disp_fc2_yaml(phono3py.phonon_dataset, phono3py.phonon_supercell, filename=filename) additional_info = get_additional_info_to_write_fc2_supercells( interface_mode, phono3py.phonon_supercell_matrix) write_supercells_with_displacements( interface_mode, phono3py.supercell, phono3py.phonon_supercells_with_displacements, optional_structure_info, zfill_width=5, additional_info=additional_info) if log_level: print("Number of displacements for special fc2: %d" % num_disps) return phono3py
def create_phono3py_supercells( cell_info, settings, symprec, output_filename=None, interface_mode="vasp", log_level=1, write_disp_yaml=False, ): """Create displacements and supercells. Distance unit used is that for the calculator interface. The default unit is Angstron. Parameters ---------- write_disp_yaml : bool Write old-style files of disp_fc3.yaml and disp_fc2.yaml. Default is False. """ optional_structure_info = cell_info["optional_structure_info"] if settings.displacement_distance is None: distance = get_default_displacement_distance(interface_mode) else: distance = settings.displacement_distance phono3py = Phono3py( cell_info["unitcell"], cell_info["supercell_matrix"], primitive_matrix=cell_info["primitive_matrix"], phonon_supercell_matrix=cell_info["phonon_supercell_matrix"], is_symmetry=settings.is_symmetry, symprec=symprec, calculator=interface_mode, ) phono3py.generate_displacements( distance=distance, cutoff_pair_distance=settings.cutoff_pair_distance, is_plusminus=settings.is_plusminus_displacement, is_diagonal=settings.is_diagonal_displacement, ) if log_level: print("") print('Unit cell was read from "%s".' % optional_structure_info[0]) print("Displacement distance: %s" % distance) if write_disp_yaml: if output_filename is None: filename = "disp_fc3.yaml" else: filename = "disp_fc3." + output_filename + ".yaml" num_disps, num_disp_files = write_disp_fc3_yaml( phono3py.dataset, phono3py.supercell, filename=filename ) ids = [] disp_cells = [] for i, cell in enumerate(phono3py.supercells_with_displacements): if cell is not None: ids.append(i + 1) disp_cells.append(cell) additional_info = get_additional_info_to_write_supercells( interface_mode, phono3py.supercell_matrix ) write_supercells_with_displacements( interface_mode, phono3py.supercell, disp_cells, optional_structure_info, displacement_ids=ids, zfill_width=5, additional_info=additional_info, ) if log_level: num_disps = len(phono3py.supercells_with_displacements) num_disp_files = len(disp_cells) print("Number of displacements: %d" % num_disps) if settings.cutoff_pair_distance is not None: print( "Cutoff distance for displacements: %s" % settings.cutoff_pair_distance ) print("Number of displacement supercell files created: %d" % num_disp_files) if phono3py.phonon_supercell_matrix is not None: if write_disp_yaml: if output_filename is None: filename = "disp_fc2.yaml" else: filename = "disp_fc2." + output_filename + ".yaml" num_disps = write_disp_fc2_yaml( phono3py.phonon_dataset, phono3py.phonon_supercell, filename=filename ) additional_info = get_additional_info_to_write_fc2_supercells( interface_mode, phono3py.phonon_supercell_matrix ) write_supercells_with_displacements( interface_mode, phono3py.supercell, phono3py.phonon_supercells_with_displacements, optional_structure_info, zfill_width=5, additional_info=additional_info, ) if log_level: print("Number of displacements for special fc2: %d" % num_disps) return phono3py
def load( phono3py_yaml=None, # phono3py.yaml-like must be the first argument. supercell_matrix=None, primitive_matrix=None, phonon_supercell_matrix=None, mesh=None, is_nac=True, calculator=None, unitcell=None, supercell=None, nac_params=None, unitcell_filename=None, supercell_filename=None, born_filename=None, forces_fc3_filename=None, forces_fc2_filename=None, fc3_filename=None, fc2_filename=None, fc_calculator=None, fc_calculator_options=None, factor=None, frequency_scale_factor=None, produce_fc=True, is_symmetry=True, symmetrize_fc=True, is_mesh_symmetry=True, is_compact_fc=False, symprec=1e-5, log_level=0): """Create Phono3py instance from parameters and/or input files. "phono3py_yaml"-like file is parsed unless crystal structure information is given by unitcell_filename, supercell_filename, unitcell (PhonopyAtoms-like), or supercell (PhonopyAtoms-like). Even when "phono3py_yaml"-like file is parse, parameters except for crystal structure can be overwritten. 'fc3.hdf5' is read if found in current directory. Unless 'fc3.hdf5' is found and if 'FORCES_FC3' and 'disp_fc3.yaml" are found, these are read and fc3 and fc2 are produced. if 'fc2.hdf5' is found, this is read. Unless 'fc2.hdf5' is found and if 'FORCES_FC2' and 'disp_fc2.yaml" are found, these are read and fc2 is produced. When force_sets_filename and force_constants_filename are not given, 'FORCES_FC3' and 'FORCES_FC2' are looked for in the current directory as the default behaviour. When 'FORCES_FC3' ('FORCES_FC2') is given in the type-1 format, 'disp_fc3.yaml' ('disp_fc2.yaml') is also necessary and read. Crystal structure ----------------- Means to provide crystal structure(s) and their priority: 1. unitcell_filename (with supercell_matrix) 2. supercell_filename 3. unitcell (with supercell_matrix) 4. supercell. 5. phono3py_yaml-like Force sets or force constants ----------------------------- Optional. Means to provide information to generate force constants and their priority: 1. fc3_filename (fc2_filename) 2. forces_fc3_filename (forces_fc2_filename). Do not forget that for type-1 format, disp_fc3.yaml (disp_fc2.yaml) has to be given, too. 3. 'fc3.hdf5' and 'fc2.hdf5' are searched in current directory. 4. 'FORCES_FC3' and 'FORCES_FC2' are searched in current directory. 'FORCES_FC2' is optional. For type-1 format, 'disp_fc3.yaml' and optionally 'disp_fc2.yaml' are also searched in current directory. When 'FORCES_FC2' is not found, 'FORCES_FC3' is used to create fc2. Parameters for non-analytical term correctiion (NAC) ---------------------------------------------------- Optional. Means to provide NAC parameters and their priority: 1. born_filename 2. nac_params 3. phono3py_yaml_like.nac_params if existed and is_nac=True. 4. 'BORN' is searched in current directory when is_nac=True. Parameters ---------- phono3py_yaml : str, optional Filename of "phono3py.yaml"-like file. If this is given, the data in the file are parsed. Default is None. supercell_matrix : array_like, optional Supercell matrix multiplied to input cell basis vectors. shape=(3, ) or (3, 3), where the former is considered a diagonal matrix. Default is the unit matrix. dtype=int primitive_matrix : array_like or str, optional Primitive matrix multiplied to input cell basis vectors. Default is the identity matrix. Default is None, which is equivalent to 'auto'. shape=(3, 3), dtype=float. When 'F', 'I', 'A', 'C', or 'R' is given instead of a 3x3 matrix, the primitive matrix defined at https://spglib.github.io/spglib/definition.html is used. phonon_supercell_matrix : array_like, optional Supercell matrix used for fc2. In phono3py, supercell matrix for fc3 and fc2 can be different to support longer range interaction of fc2 than that of fc3. Unless setting this, supercell_matrix is used. This is only valide when unitcell or unitcell_filename is given. Default is None. mesh : array_like, optional Grid mesh numbers in reciprocal cell. shape=(3,), dtype='intc' is_nac : bool, optional If True, look for 'BORN' file. If False, NAS is turned off. Default is True. calculator : str, optional. Calculator used for computing forces. This is used to switch the set of physical units. Default is None, which is equivalent to "vasp". unitcell : PhonopyAtoms, optional Input unit cell. Default is None. supercell : PhonopyAtoms, optional Input supercell. With given, default value of primitive_matrix is set to 'auto' (can be overwitten). supercell_matrix is ignored. Default is None. nac_params : dict, optional Parameters required for non-analytical term correction. Default is None. {'born': Born effective charges (array_like, shape=(primitive cell atoms, 3, 3), dtype=float), 'dielectric': Dielectric constant matrix (array_like, shape=(3, 3), dtype=float), 'factor': unit conversion facotr (float)} unitcell_filename : str, optional Input unit cell filename. Default is None. supercell_filename : str, optional Input supercell filename. When this is specified, supercell_matrix is ignored. Default is None. born_filename : str, optional Filename corresponding to 'BORN', a file contains non-analytical term correction parameters. forces_fc3_filename : sequence or str, optional A two-elemental sequence of filenames corresponding to ('FORCES_FC3', 'disp_fc3.yaml') in the type-1 format or a filename (str) corresponding to 'FORCES_FC3' in the type-2 format. Default is None. forces_fc2_filename : str or tuple, optional A two-elemental sequence of filenames corresponding to ('FORCES_FC2', 'disp_fc2.yaml') in the type-1 format or a filename (str) corresponding to 'FORCES_FC2' in the type-2 format. Default is None. fc3_filename : str, optional Filename of a file corresponding to 'fc3.hdf5', a file contains third-order force constants. Default is None. fc2_filename : str, optional Filename of a file corresponding to 'fc2.hdf5', a file contains second-order force constants. Default is None. fc_calculator : str, optional Force constants calculator. Currently only 'alm'. Default is None. fc_calculator_options : str, optional Optional parameters that are passed to the external fc-calculator. This is given as one text string. How to parse this depends on the fc-calculator. For alm, each parameter is splitted by comma ',', and each set of key and value pair is written in 'key = value'. factor : float, optional Phonon frequency unit conversion factor. Unless specified, default unit conversion factor for each calculator is used. frequency_scale_factor : float, optional Factor multiplied to calculated phonon frequency. Default is None, i.e., effectively 1. produce_fc : bool, optional Setting False, force constants are not calculated from displacements and forces. Default is True. is_symmetry : bool, optional Setting False, crystal symmetry except for lattice translation is not considered. Default is True. symmetrize_fc : bool, optional Setting False, force constants are not symmetrized when creating force constants from displacements and forces. Default is True. is_mesh_symmetry : bool, optional Setting False, reciprocal mesh symmetry is not considered. Default is True. is_compact_fc : bool fc3 are created in the array whose shape is True: (primitive, supercell, supecell, 3, 3, 3) False: (supercell, supercell, supecell, 3, 3, 3) and for fc2 True: (primitive, supecell, 3, 3) False: (supercell, supecell, 3, 3) where 'supercell' and 'primitive' indicate number of atoms in these cells. Default is False. symprec : float, optional Tolerance used to find crystal symmetry. Default is 1e-5. log_level : int, optional Verbosity control. Default is 0. """ if (supercell is not None or supercell_filename is not None or unitcell is not None or unitcell_filename is not None): cell, smat, pmat = load_helper.get_cell_settings( supercell_matrix=supercell_matrix, primitive_matrix=primitive_matrix, unitcell=unitcell, supercell=supercell, unitcell_filename=unitcell_filename, supercell_filename=supercell_filename, calculator=calculator, symprec=symprec) if phonon_supercell_matrix is not None: if unitcell is None and unitcell_filename is None: msg = ("phonon_supercell_matrix can be used only when " "unitcell or unitcell_filename is given.") raise RuntimeError(msg) ph_smat = phonon_supercell_matrix else: ph_smat = None _nac_params = nac_params ph3py_yaml = None elif phono3py_yaml is not None: ph3py_yaml = Phono3pyYaml() ph3py_yaml.read(phono3py_yaml) cell = ph3py_yaml.unitcell smat = ph3py_yaml.supercell_matrix ph_smat = ph3py_yaml.phonon_supercell_matrix if smat is None: smat = np.eye(3, dtype='intc', order='C') if primitive_matrix == 'auto': pmat = 'auto' else: pmat = ph3py_yaml.primitive_matrix if nac_params is not None: _nac_params = nac_params elif is_nac: _nac_params = ph3py_yaml.nac_params else: _nac_params = None # units keywords: factor, nac_factor, distance_to_A physical_units = get_default_physical_units(calculator) if factor is None: _factor = physical_units['factor'] else: _factor = factor ph3py = Phono3py(cell, smat, primitive_matrix=pmat, phonon_supercell_matrix=ph_smat, frequency_factor_to_THz=_factor, symprec=symprec, is_symmetry=is_symmetry, is_mesh_symmetry=is_mesh_symmetry, calculator=calculator, log_level=log_level) ph3py.mesh_number = mesh # NAC params if (born_filename is not None or nac_params is not None or is_nac and os.path.isfile("BORN")): ph3py.nac_params = load_helper.get_nac_params( ph3py.primitive, _nac_params, born_filename, is_nac, physical_units['nac_factor'], log_level=log_level) set_dataset_and_force_constants( ph3py, ph3py_yaml=ph3py_yaml, fc3_filename=fc3_filename, fc2_filename=fc2_filename, forces_fc3_filename=forces_fc3_filename, forces_fc2_filename=forces_fc2_filename, fc_calculator=fc_calculator, fc_calculator_options=fc_calculator_options, produce_fc=produce_fc, symmetrize_fc=symmetrize_fc, is_compact_fc=is_compact_fc, log_level=log_level) if mesh is not None: ph3py.init_phph_interaction( frequency_scale_factor=frequency_scale_factor) return ph3py
def set_dataset_and_force_constants( ph3py: Phono3py, ph3py_yaml: typing.Union[Phono3pyYaml, None] = None, fc3_filename=None, fc2_filename=None, forces_fc3_filename=None, forces_fc2_filename=None, fc_calculator=None, fc_calculator_options=None, produce_fc=True, symmetrize_fc=True, is_compact_fc=False, cutoff_pair_distance=None, log_level=0, ): """Set displacements, forces, and create force constants.""" read_fc = {"fc2": False, "fc3": False} p2s_map = ph3py.primitive.p2s_map phonon_p2s_map = ph3py.phonon_primitive.p2s_map if fc3_filename is not None: fc3 = read_fc3_from_hdf5(filename=fc3_filename, p2s_map=p2s_map) ph3py.fc3 = fc3 read_fc["fc3"] = True if log_level: print('fc3 was read from "%s".' % fc3_filename) elif forces_fc3_filename is not None: if type(forces_fc3_filename) is str: force_filename = forces_fc3_filename disp_filename = None else: force_filename, disp_filename = forces_fc3_filename _set_forces_fc3( ph3py, ph3py_yaml, force_filename, disp_filename, produce_fc, symmetrize_fc, is_compact_fc, fc_calculator, fc_calculator_options, cutoff_pair_distance, log_level, ) elif os.path.isfile("fc3.hdf5"): ph3py.fc3 = read_fc3_from_hdf5(filename="fc3.hdf5", p2s_map=p2s_map) read_fc["fc3"] = True if log_level: print('fc3 was read from "fc3.hdf5".') elif os.path.isfile("FORCES_FC3"): disp_filename = None if os.path.isfile("disp_fc3.yaml"): if ph3py_yaml is None: disp_filename = "disp_fc3.yaml" elif ph3py_yaml.dataset is None: disp_filename = "disp_fc3.yaml" _set_forces_fc3( ph3py, ph3py_yaml, "FORCES_FC3", disp_filename, produce_fc, symmetrize_fc, is_compact_fc, fc_calculator, fc_calculator_options, cutoff_pair_distance, log_level, ) elif ( ph3py_yaml is not None and ph3py_yaml.dataset is not None and forces_in_dataset(ph3py_yaml.dataset) ): _set_forces_fc3( ph3py, ph3py_yaml, None, None, produce_fc, symmetrize_fc, is_compact_fc, fc_calculator, fc_calculator_options, cutoff_pair_distance, log_level, ) if log_level and ph3py.fc3 is not None: show_drift_fc3(ph3py.fc3, primitive=ph3py.primitive) if fc2_filename is not None: fc2 = read_fc2_from_hdf5(filename=fc2_filename, p2s_map=phonon_p2s_map) ph3py.fc2 = fc2 read_fc["fc2"] = True if log_level: print('fc2 was read from "%s".' % fc2_filename) elif forces_fc2_filename is not None: if type(forces_fc2_filename) is str: force_filename = forces_fc2_filename disp_filename = None else: force_filename, disp_filename = forces_fc2_filename _set_forces_fc2( ph3py, ph3py_yaml, force_filename, disp_filename, produce_fc, symmetrize_fc, is_compact_fc, fc_calculator, fc_calculator_options, "phonon_fc2", log_level, ) elif os.path.isfile("fc2.hdf5"): ph3py.fc2 = read_fc2_from_hdf5(filename="fc2.hdf5", p2s_map=phonon_p2s_map) read_fc["fc2"] = True if log_level: print('fc2 was read from "fc2.hdf5".') elif os.path.isfile("FORCES_FC2"): disp_filename = None if os.path.isfile("disp_fc2.yaml"): if ph3py_yaml is None: disp_filename = "disp_fc2.yaml" elif ph3py_yaml.phonon_dataset is None: disp_filename = "disp_fc2.yaml" if ( disp_filename is None and ph3py_yaml is not None and ph3py_yaml.phonon_dataset is None ): msg = ( '"FORCES_FC2" was found. But phonon displacement dataset ' f'was not found in "{ph3py_yaml.yaml_filename}".' ) raise RuntimeError(msg) _set_forces_fc2( ph3py, ph3py_yaml, "FORCES_FC2", disp_filename, produce_fc, symmetrize_fc, is_compact_fc, fc_calculator, fc_calculator_options, "phonon_fc2", log_level, ) elif ( ph3py.phonon_supercell_matrix is None and fc_calculator == "alm" and ph3py.fc2 is not None ): if log_level: print("fc2 that was fit simultaneously with fc3 by ALM is used.") elif ( ph3py_yaml is not None and ph3py_yaml.phonon_dataset is not None and forces_in_dataset(ph3py_yaml.phonon_dataset) ): _set_forces_fc2( ph3py, ph3py_yaml, None, None, produce_fc, symmetrize_fc, is_compact_fc, fc_calculator, fc_calculator_options, "phonon_fc2", log_level, ) elif ( ph3py_yaml is not None and ph3py_yaml.dataset is not None and forces_in_dataset(ph3py_yaml.dataset) ): _set_forces_fc2( ph3py, ph3py_yaml, None, None, produce_fc, symmetrize_fc, is_compact_fc, fc_calculator, fc_calculator_options, "fc2", log_level, ) elif os.path.isfile("FORCES_FC3"): # suppose fc3.hdf5 is read but fc2.hdf5 doesn't exist. disp_filename = None if os.path.isfile("disp_fc3.yaml"): if ph3py_yaml is None: disp_filename = "disp_fc3.yaml" elif ph3py_yaml.dataset is None: disp_filename = "disp_fc3.yaml" _set_forces_fc2( ph3py, ph3py_yaml, "FORCES_FC3", disp_filename, produce_fc, symmetrize_fc, is_compact_fc, fc_calculator, fc_calculator_options, "fc2", log_level, ) if log_level and ph3py.fc2 is not None: show_drift_force_constants( ph3py.fc2, primitive=ph3py.phonon_primitive, name="fc2" ) # Cases that dataset is in phono3py.yaml but not forces. if ph3py.dataset is None: if ph3py_yaml is not None and ph3py_yaml.dataset is not None: ph3py.dataset = ph3py_yaml.dataset if ph3py_yaml is not None and ph3py_yaml.phonon_dataset is not None: ph3py.phonon_dataset = ph3py_yaml.phonon_dataset return read_fc
def create_phono3py_supercells(unitcell, supercell_matrix, phonon_supercell_matrix, displacement_distance, is_plusminus, is_diagonal, cutoff_pair_distance, write_supercells_with_displacements, optional_structure_file_information, is_symmetry, symprec, interface_mode='vasp', output_filename=None, log_level=1): if displacement_distance is None: if interface_mode in ('qe', 'abinit', 'turbomole'): distance = 0.06 elif interface_mode == 'crystal': distance = 0.03 else: distance = 0.03 else: distance = displacement_distance phono3py = Phono3py( unitcell, supercell_matrix, phonon_supercell_matrix=phonon_supercell_matrix, is_symmetry=is_symmetry, symprec=symprec) supercell = phono3py.get_supercell() phono3py.generate_displacements( distance=distance, cutoff_pair_distance=cutoff_pair_distance, is_plusminus=is_plusminus, is_diagonal=is_diagonal) dds = phono3py.get_displacement_dataset() if log_level: print('') print("Displacement distance: %s" % distance) if output_filename is None: filename = 'disp_fc3.yaml' else: filename = 'disp_fc3.' + output_filename + '.yaml' num_disps, num_disp_files = write_disp_fc3_yaml(dds, supercell, filename=filename) cells_with_disps = phono3py.get_supercells_with_displacements() if interface_mode == 'qe': pp_filenames = optional_structure_file_information[1] write_supercells_with_displacements(supercell, cells_with_disps, pp_filenames, width=5) elif interface_mode == 'crystal': conv_numbers = optional_structure_file_information[1] # N_FC3 = num_unitcells_in_supercell (here for FC3 supercell) N_FC3 = abs(determinant(supercell_matrix)) write_supercells_with_displacements(supercell, cells_with_disps, conv_numbers, N_FC3, width=5, template_file="TEMPLATE3") elif interface_mode == 'abinit': write_supercells_with_displacements(supercell, cells_with_disps, width=5) elif interface_mode == 'turbomole': write_supercells_with_displacements(supercell, cells_with_disps, width=5) else: # VASP write_supercells_with_displacements(supercell, cells_with_disps, width=5) if log_level: print("Number of displacements: %d" % num_disps) if cutoff_pair_distance is not None: print("Cutoff distance for displacements: %s" % cutoff_pair_distance) print("Number of displacement supercell files created: %d" % num_disp_files) if phonon_supercell_matrix is not None: phonon_dds = phono3py.get_phonon_displacement_dataset() phonon_supercell = phono3py.get_phonon_supercell() if output_filename is None: filename = 'disp_fc2.yaml' else: filename = 'disp_fc2.' + output_filename + '.yaml' num_disps = write_disp_fc2_yaml(phonon_dds, phonon_supercell, filename=filename) cells_with_disps = phono3py.get_phonon_supercells_with_displacements() if interface_mode == 'qe': pp_filenames = optional_structure_file_information[1] write_supercells_with_displacements(phonon_supercell, cells_with_disps, pp_filenames, pre_filename="supercell_fc2", width=5) elif interface_mode == 'crystal': conv_numbers = optional_structure_file_information[1] # N = num_unitcells_in_supercell (here for FC2 supercell) N_FC2 = abs(determinant(phonon_supercell_matrix)) write_supercells_with_displacements(phonon_supercell, cells_with_disps, conv_numbers, N_FC2, pre_filename="supercell_fc2", width=5, template_file="TEMPLATE") elif interface_mode == 'abinit': write_supercells_with_displacements(phonon_supercell, cells_with_disps, pre_filename="supercell_fc2", width=5) elif interface_mode == 'turbomole': write_supercells_with_displacements(phonon_supercell, cells_with_disps, pre_filename="supercell_fc2", width=5) else: write_supercells_with_displacements(phonon_supercell, cells_with_disps, pre_filename="POSCAR_FC2", width=5) if log_level: print("Number of displacements for special fc2: %d" % num_disps) return phono3py