Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
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
Ejemplo n.º 4
0
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")
Ejemplo n.º 5
0
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()
Ejemplo n.º 6
0
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")
Ejemplo n.º 7
0
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
Ejemplo n.º 8
0
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