Exemple #1
0
    def run_wannier90(self):
        try:
            remote_folder = self.ctx.calc_pw2wannier90.outputs.remote_folder
        except AttributeError:
            self.report(
                'the Pw2wannier90Calculation did not output a remote_folder node'
            )
            return self.exit_codes.ERROR_SUB_PROCESS_FAILED_WANNIER90

        # we need metadata in exposed_inputs
        inputs = AttributeDict(
            self.exposed_inputs(Wannier90Calculation, namespace='wannier90'))
        pp_inputs = self.ctx.calc_wannier90_pp.inputs
        pp_keys = [
            'code', 'parameters', 'kpoint_path', 'structure', 'kpoints',
            'settings'
        ]
        for key in pp_keys:
            inputs[key] = pp_inputs[key]

        inputs['remote_input_folder'] = remote_folder

        settings = inputs.settings.get_dict()
        settings['postproc_setup'] = False
        inputs.settings = settings

        inputs = prepare_process_inputs(Wannier90Calculation, inputs)
        running = self.submit(Wannier90Calculation, **inputs)

        self.report(
            'wannier90 step - launching Wannier90Calculation<{}>'.format(
                running.pk))

        return ToContext(calc_wannier90=running)
Exemple #2
0
    def run_relax(self):
        """
        Run the PwRelaxWorkChain to run a relax calculation
        """
        inputs = AttributeDict(
            self.exposed_inputs(PwRelaxWorkChain, namespace='relax'))
        inputs.structure = self.ctx.current_structure

        running = self.submit(PwRelaxWorkChain, **inputs)

        self.report('launching PwRelaxWorkChain<{}>'.format(running.pk))

        return ToContext(workchain_relax=running)
Exemple #3
0
    def run_pw2wannier90(self):
        inputs = AttributeDict(
            self.exposed_inputs(Pw2wannier90Calculation,
                                namespace='pw2wannier90'))

        try:
            remote_folder = self.ctx.workchain_nscf.outputs.remote_folder
        except AttributeError:
            return self.exit_codes.ERROR_SUB_PROCESS_FAILED_PW2WANNIER90(
                'the nscf WorkChain did not output a remote_folder node')

        inputs['parent_folder'] = remote_folder
        inputs['nnkp_file'] = self.ctx.calc_wannier90_pp.outputs.nnkp_file
        inputs.parameters = inputs.parameters.get_dict()
        inputs.parameters['inputpp'].update({
            'write_mmn': True,
            'write_amn': True,
        })

        if self.ctx.auto_projections:
            inputs.parameters['inputpp']['scdm_proj'] = True

            # TODO: if exclude_band: gaussian
            # TODO: auto check if is insulator?
            if self.inputs.only_valence:
                inputs.parameters['inputpp']['scdm_entanglement'] = 'isolated'
            else:
                inputs.parameters['inputpp']['scdm_entanglement'] = 'erfc'
                try:
                    inputs.parameters = update_pw2wan_params_mu_sigma(
                        parameters=orm.Dict(dict=inputs.parameters),
                        wannier_parameters=self.ctx.calc_wannier90_pp.inputs.
                        parameters,
                        bands=self.ctx.calc_projwfc.outputs.bands,
                        projections=self.ctx.calc_projwfc.outputs.projections,
                        thresholds=self.inputs.get('scdm_thresholds'))
                except ValueError:
                    self.report(
                        'WARNING: update_pw2wan_params_mu_sigma failed!')
                    return self.exit_codes.ERROR_SUB_PROCESS_FAILED_PW2WANNIER90

        inputs = prepare_process_inputs(Pw2wannier90Calculation, inputs)
        running = self.submit(Pw2wannier90Calculation, **inputs)

        self.report(
            'pw2wannier90 step - launching Pw2Wannier90Calculation<{}>'.format(
                running.pk))
        return ToContext(calc_pw2wannier90=running)
Exemple #4
0
    def run_projwfc(self):
        """
        Projwfc step
        :return:
        """
        inputs = AttributeDict(
            self.exposed_inputs(ProjwfcCalculation, namespace='projwfc'))
        inputs.parent_folder = self.ctx.current_folder

        inputs = prepare_process_inputs(ProjwfcCalculation, inputs)
        running = self.submit(ProjwfcCalculation, **inputs)

        self.report('projwfc step - launching ProjwfcCalculation<{}>'.format(
            running.pk))

        return ToContext(calc_projwfc=running)
Exemple #5
0
    def run_scf(self):
        """
        Run the PwBaseWorkChain in scf mode on the primitive cell of (optionally relaxed) input structure.
        """
        inputs = AttributeDict(
            self.exposed_inputs(PwBaseWorkChain, namespace='scf'))
        inputs.pw.structure = self.ctx.current_structure
        inputs.pw.parameters = inputs.pw.parameters.get_dict()
        inputs.pw.parameters.setdefault('CONTROL', {})
        inputs.pw.parameters['CONTROL']['calculation'] = 'scf'

        inputs = prepare_process_inputs(PwBaseWorkChain, inputs)
        running = self.submit(PwBaseWorkChain, **inputs)

        self.report(
            'scf step - launching PwBaseWorkChain<{}> in {} mode'.format(
                running.pk, 'scf'))

        return ToContext(workchain_scf=running)
Exemple #6
0
    def run_wannier90_pp(self):
        """The input of wannier90 calculation is build here.

        :return: [description]
        :rtype: [type]
        """
        inputs = AttributeDict(
            self.exposed_inputs(Wannier90Calculation, namespace='wannier90'))
        inputs.structure = self.ctx.current_structure
        parameters = inputs.parameters.get_dict()

        # get nscf kmesh
        inputs.kpoints = self.ctx.workchain_nscf.inputs.kpoints
        # the input kpoints of nscf is an explicitly generated list of kpoints,
        # we mush retrieve the original kmesh, and explicitly set w90 mp_grid keyword
        parameters['mp_grid'] = self.ctx.nscf_kmesh.get_kpoints_mesh()[0]

        # check num_bands, exclude_bands, nscf nbnd
        nbnd = self.ctx.workchain_nscf.outputs.output_parameters.get_dict(
        )['number_of_bands']
        num_ex_bands = len(get_exclude_bands(inputs.parameters.get_dict()))
        parameters['num_bands'] = nbnd - num_ex_bands

        # set num_wann for auto_projections
        if self.ctx.auto_projections:
            if self.inputs.only_valence:
                parameters['num_wann'] = parameters['num_bands']
                inputs.parameters = orm.Dict(dict=parameters)
            else:
                inputs.parameters = orm.Dict(dict=parameters)
                inputs.parameters = update_w90_params_numwann(
                    inputs.parameters,
                    self.ctx.calc_projwfc.outputs.projections)
                self.report(
                    'number of Wannier functions extracted from projections: '
                    + str(inputs.parameters['num_wann']))

        # get scf Fermi energy
        try:
            energies_relative_to_fermi = self.inputs.get(
                'wannier_energies_relative_to_fermi')
            inputs.parameters = update_w90_params_fermi(
                inputs.parameters,
                self.ctx.workchain_scf.outputs.output_parameters,
                energies_relative_to_fermi)
        except TypeError:
            self.report("Error in retriving the SCF Fermi energy "
                        "from pk: {}".format(self.ctx.workchain_scf))
            return self.exit_codes.ERROR_SUB_PROCESS_FAILED_WANNIER90PP

        #Check if settings is given in input
        try:
            settings = inputs['settings'].get_dict()
        except KeyError:
            settings = {}
        settings['postproc_setup'] = True
        inputs['settings'] = settings

        inputs = prepare_process_inputs(Wannier90Calculation, inputs)
        running = self.submit(Wannier90Calculation, **inputs)

        self.report(
            'wannier90 postproc step - launching Wannier90Calculation<{}> in postproc mode'
            .format(running.pk))

        return ToContext(calc_wannier90_pp=running)
Exemple #7
0
    def run_nscf(self):
        """
        Run the PwBaseWorkChain in nscf mode
        """
        inputs = AttributeDict(
            self.exposed_inputs(PwBaseWorkChain, namespace='nscf'))
        inputs.pw.structure = self.ctx.current_structure
        inputs.pw.parent_folder = self.ctx.current_folder
        inputs.pw.parameters = inputs.pw.parameters.get_dict()
        inputs.pw.parameters.setdefault('CONTROL', {})
        inputs.pw.parameters.setdefault('SYSTEM', {})
        inputs.pw.parameters.setdefault('ELECTRONS', {})
        inputs.pw.parameters['CONTROL']['restart_mode'] = 'from_scratch'
        inputs.pw.parameters['CONTROL']['calculation'] = 'nscf'
        inputs.pw.parameters['SYSTEM']['nosym'] = True
        inputs.pw.parameters['SYSTEM']['noinv'] = True
        inputs.pw.parameters['ELECTRONS']['diagonalization'] = 'cg'
        inputs.pw.parameters['ELECTRONS']['diago_full_acc'] = True

        if self.inputs.only_valence:
            inputs.pw.parameters['SYSTEM']['occupations'] = 'fixed'
            inputs.pw.parameters['SYSTEM'].pop(
                'smearing', None)  # pop None to avoid KeyError
            inputs.pw.parameters['SYSTEM'].pop(
                'degauss', None)  # pop None to avoid KeyError

        # inputs.pw.pseudos is an AttributeDict, but calcfunction only accepts
        # orm.Data, so we unpack it to pass in orm.UpfData
        inputs.pw.parameters = update_nscf_num_bands(
            orm.Dict(dict=inputs.pw.parameters),
            self.ctx.workchain_scf.outputs.output_parameters,
            self.ctx.current_structure, self.inputs.only_valence,
            **inputs.pw.pseudos)
        self.report('nscf number of bands set as ' +
                    str(inputs.pw.parameters['SYSTEM']['nbnd']))

        # check kmesh
        try:
            inputs.kpoints
        except AttributeError:
            # then kpoints_distance must exists, since this is ensured by inputs check of this workchain
            from aiida_quantumespresso.workflows.functions.create_kpoints_from_distance import create_kpoints_from_distance
            force_parity = inputs.get('kpoints_force_parity', orm.Bool(False))
            kmesh = create_kpoints_from_distance(self.ctx.current_structure,
                                                 inputs.kpoints_distance,
                                                 force_parity)
            #kpoints_data = orm.KpointsData()
            # kpoints_data.set_cell_from_structure(self.ctx.current_structure)
            # kmesh = kpoints_data.set_kpoints_mesh_from_density(inputs.kpoints_distance.value)
        else:
            try:
                inputs.kpoints.get_kpoints_mesh()
            except AttributeError:
                self.report("nscf only support `mesh' type KpointsData")
                return self.exit_codes.ERROR_SUB_PROCESS_FAILED_NSCF
            else:
                kmesh = inputs.kpoints
        # convert kmesh to explicit list, since auto generated kpoints
        # maybe different between QE & Wannier90. Here we explicitly
        # generate a list of kpoint to avoid discrepencies between
        # QE's & Wannier90's automatically generated kpoints.
        self.ctx.nscf_kmesh = kmesh  # store it since it will be used by w90
        inputs.kpoints = convert_kpoints_mesh_to_list(kmesh)

        inputs = prepare_process_inputs(PwBaseWorkChain, inputs)
        running = self.submit(PwBaseWorkChain, **inputs)

        self.report(
            'nscf step - launching PwBaseWorkChain<{}> in {} mode'.format(
                running.pk, 'nscf'))

        return ToContext(workchain_nscf=running)