Ejemplo n.º 1
0
    def parse(self, **kwargs):
        """Parse the retrieved files from a `MatdynCalculation`."""
        try:
            output_folder = self.retrieved
        except exceptions.NotExistent:
            return self.exit(self.exit_codes.ERROR_NO_RETRIEVED_FOLDER)

        filename_stdout = self.node.get_option('output_filename')
        filename_frequencies = MatdynCalculation._PHONON_FREQUENCIES_NAME

        if filename_stdout not in output_folder.list_object_names():
            return self.exit(self.exit_codes.ERROR_OUTPUT_STDOUT_READ)

        if 'JOB DONE' not in output_folder.get_object_content(filename_stdout):
            return self.exit(self.exit_codes.ERROR_OUTPUT_STDOUT_INCOMPLETE)

        if filename_frequencies not in output_folder.list_object_names():
            return self.exit(self.exit_codes.ERROR_OUTPUT_STDOUT_READ)

        # Extract the kpoints from the input data and create the `KpointsData` for the `BandsData`
        try:
            kpoints = self.node.inputs.kpoints.get_kpoints()
            kpoints_for_bands = self.node.inputs.kpoints.clone()
        except AttributeError:
            kpoints = self.node.inputs.kpoints.get_kpoints_mesh(
                print_list=True)
            kpoints_for_bands = orm.KpointsData()
            kpoints_for_bands.set_kpoints(kpoints)

        parsed_data = parse_raw_matdyn_phonon_file(
            output_folder.get_object_content(filename_frequencies))

        try:
            num_kpoints = parsed_data.pop('num_kpoints')
        except KeyError:
            return self.exit(self.exit_codes.ERROR_OUTPUT_KPOINTS_MISSING)

        if num_kpoints != kpoints.shape[0]:
            return self.exit(
                self.exit_codes.ERROR_OUTPUT_KPOINTS_INCOMMENSURATE)

        output_bands = orm.BandsData()
        output_bands.set_kpointsdata(kpoints_for_bands)
        output_bands.set_bands(parsed_data.pop('phonon_bands'), units='THz')

        for message in parsed_data['warnings']:
            self.logger.error(message)

        self.out('output_parameters', orm.Dict(dict=parsed_data))
        self.out('output_phonon_bands', output_bands)

        return
Ejemplo n.º 2
0
def crop_bands_inline(bands, kpoints):
    """
    Crop a BandsData to the given kpoints by removing from the front.
    """
    # check consistency of kpoints
    kpoints_array = kpoints.get_kpoints()
    band_slice = slice(-len(kpoints_array), None)
    cropped_bands_kpoints = bands.get_kpoints()[band_slice]
    assert np.allclose(cropped_bands_kpoints, kpoints_array)

    cropped_bands = orm.BandsData()
    cropped_bands.set_kpointsdata(kpoints)
    cropped_bands_array = bands.get_bands()[band_slice]
    cropped_bands.set_bands(cropped_bands_array)
    return {'bands': cropped_bands}
Ejemplo n.º 3
0
    def build_output_bands(self, parsed_bands, parsed_kpoints=None):
        """Build the output bands from the raw parsed bands data.

        :param parsed_bands: the raw parsed bands data
        :param parsed_kpoints: the `KpointsData` to use for the bands
        :return: a `BandsData` or None
        """
        if not parsed_bands or not parsed_kpoints:
            return

        # In the case of input kpoints that define a list of k-points, i.e. along high-symmetry path, and explicit
        # labels, set those labels also on the output kpoints to be used for the bands. This will allow plotting
        # utilities to place k-point labels along the x-axis.
        try:
            self.node.inputs.kpoints.get_kpoints()
            parsed_kpoints.labels = self.node.inputs.kpoints.labels
        except (AttributeError, ValueError, TypeError):
            # AttributeError: input kpoints defines a mesh, not an explicit list
            # TypeError: inputs kpoints do not define any labels
            # ValueError: input kpoints labels are not commensurate with `parsed_kpoints`
            pass

        # Correct the occupation for nspin=1 calculations where Quantum ESPRESSO populates each band only halfway
        if len(parsed_bands['occupations']) > 1:
            occupations = parsed_bands['occupations']
        else:
            occupations = 2. * numpy.array(parsed_bands['occupations'][0])

        if len(parsed_bands['bands']) > 1:
            bands_energies = parsed_bands['bands']
        else:
            bands_energies = parsed_bands['bands'][0]

        bands = orm.BandsData()
        bands.set_kpointsdata(parsed_kpoints)
        bands.set_bands(bands_energies,
                        units=parsed_bands['bands_units'],
                        occupations=occupations)

        return bands
Ejemplo n.º 4
0
def window_search_builder(test_data_dir, code_wannier90):  # pylint: disable=too-many-locals,useless-suppression
    """
    Sets up the process builder for window_search tests, and adds the inputs.
    """

    builder = WindowSearch.get_builder()

    input_folder = orm.FolderData()
    input_folder_path = test_data_dir / 'wannier_input_folder'
    for filename in os.listdir(input_folder_path):
        input_folder.put_object_from_file(
            path=str((input_folder_path / filename).resolve()), key=filename
        )
    builder.wannier.local_input_folder = input_folder

    builder.wannier.code = code_wannier90
    builder.code_tbmodels = orm.Code.get_from_string('tbmodels')

    builder.model_evaluation_workflow = BandDifferenceModelEvaluation
    # print(builder.model_evaluation.dynamic)
    builder.model_evaluation = {
        'code_bands_inspect': orm.Code.get_from_string('bands_inspect'),
    }
    builder.reference_bands = read(test_data_dir / 'bands.hdf5')

    initial_window = orm.List()
    initial_window.extend([-4.5, -4, 6.5, 16])
    builder.initial_window = initial_window
    builder.window_tol = orm.Float(1.5)

    a = 3.2395  # pylint: disable=invalid-name
    structure = orm.StructureData()
    structure.set_pymatgen_structure(
        pymatgen.Structure(
            lattice=[[0, a, a], [a, 0, a], [a, a, 0]],
            species=['In', 'Sb'],
            coords=[[0] * 3, [0.25] * 3]
        )
    )
    builder.structure = structure
    wannier_parameters = orm.Dict(
        dict=dict(
            num_wann=14,
            num_bands=36,
            dis_num_iter=1000,
            num_iter=0,
            spinors=True,
            mp_grid=[6, 6, 6],
        )
    )
    builder.wannier.parameters = wannier_parameters
    builder.wannier.metadata.options = {
        'resources': {
            'num_machines': 1,
            'tot_num_mpiprocs': 1
        },
        'withmpi': False
    }

    builder.symmetries = orm.SinglefileData(
        file=str((test_data_dir / 'symmetries.hdf5').resolve())
    )
    slice_idx = orm.List()
    slice_idx.extend([0, 2, 3, 1, 5, 6, 4, 7, 9, 10, 8, 12, 13, 11])
    builder.slice_idx = slice_idx

    k_values = [
        x if x <= 0.5 else -1 + x
        for x in np.linspace(0, 1, 6, endpoint=False)
    ]
    k_points = [
        list(reversed(k)) for k in itertools.product(k_values, repeat=3)
    ]
    wannier_bands = orm.BandsData()
    wannier_bands.set_kpoints(k_points)
    # Just let every energy window be valid.
    wannier_bands.set_bands(np.array([[0] * 14] * len(k_points)))
    builder.wannier_bands = wannier_bands
    return builder
Ejemplo n.º 5
0
    def inner(window_values, slice_, symmetries):
        builder = RunWindow.get_builder()

        input_folder = orm.FolderData()
        input_folder_path = test_data_dir / 'wannier_input_folder'
        for filename in os.listdir(input_folder_path):
            input_folder.put_object_from_file(path=str(
                (input_folder_path / filename).resolve()),
                                              key=filename)
        builder.wannier.local_input_folder = input_folder

        builder.wannier.code = code_wannier90
        builder.code_tbmodels = orm.Code.get_from_string('tbmodels')
        builder.model_evaluation_workflow = BandDifferenceModelEvaluation
        builder.reference_bands = read(test_data_dir / 'bands.hdf5')
        builder.model_evaluation = {
            'code_bands_inspect': orm.Code.get_from_string('bands_inspect'),
        }

        window = orm.List(list=window_values)
        builder.window = window

        k_values = [
            x if x <= 0.5 else -1 + x
            for x in np.linspace(0, 1, 6, endpoint=False)
        ]
        k_points = [
            list(reversed(k)) for k in itertools.product(k_values, repeat=3)
        ]
        wannier_kpoints = orm.KpointsData()
        wannier_kpoints.set_kpoints(k_points)
        builder.wannier.kpoints = wannier_kpoints

        wannier_bands = orm.BandsData()
        wannier_bands.set_kpoints(k_points)
        # Just let every energy window be valid.
        wannier_bands.set_bands(
            np.array([[-20] * 10 + [-0.5] * 7 + [0.5] * 7 + [20] * 12] *
                     len(k_points)))
        builder.wannier_bands = wannier_bands

        a = 3.2395  # pylint: disable=invalid-name
        structure = orm.StructureData()
        structure.set_pymatgen_structure(
            pymatgen.Structure(lattice=[[0, a, a], [a, 0, a], [a, a, 0]],
                               species=['In', 'Sb'],
                               coords=[[0] * 3, [0.25] * 3]))
        builder.structure = structure
        wannier_parameters = orm.Dict(dict=dict(
            num_wann=14,
            num_bands=36,
            dis_num_iter=1000,
            num_iter=0,
            spinors=True,
            mp_grid=[6, 6, 6],
        ))
        builder.wannier.parameters = wannier_parameters
        builder.wannier.metadata.options = {
            'resources': {
                'num_machines': 1,
                'tot_num_mpiprocs': 1
            },
            'withmpi': False
        }
        if symmetries:
            builder.symmetries = orm.SinglefileData(
                file=str(test_data_dir / 'symmetries.hdf5'))
        if slice_:
            slice_idx = orm.List()
            slice_idx.extend([0, 2, 3, 1, 5, 6, 4, 7, 9, 10, 8, 12, 13, 11])
            builder.slice_idx = slice_idx
        return builder