Beispiel #1
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)
Beispiel #2
0
    def _generate_projwfc_inputs(self):
        """Run Projwfc calculation, to generate partial Densities of State."""
        projwfc_inputs = AttributeDict(self.exposed_inputs(ProjwfcCalculation, 'projwfc'))
        projwfc_inputs.parent_folder = self.ctx.nscf_parent_folder
        projwfc_parameters = self.inputs.projwfc.parameters.get_dict()

        if projwfc_parameters.pop('align_to_fermi', False):
            projwfc_parameters['PROJWFC']['Emin'] = projwfc_parameters['Emin'] + self.ctx.nscf_fermi
            projwfc_parameters['PROJWFC']['Emax'] = projwfc_parameters['Emax'] + self.ctx.nscf_fermi

        projwfc_inputs.parameters = orm.Dict(dict=projwfc_parameters)
        projwfc_inputs['metadata']['call_link_label'] = 'projwfc'
        return projwfc_inputs
Beispiel #3
0
    def _generate_dos_inputs(self):
        """Run DOS calculation, to generate total Densities of State."""
        dos_inputs = AttributeDict(self.exposed_inputs(DosCalculation, 'dos'))
        dos_inputs.parent_folder = self.ctx.nscf_parent_folder
        dos_parameters = self.inputs.dos.parameters.get_dict()

        if dos_parameters.pop('align_to_fermi', False):
            dos_parameters['DOS']['Emin'] = dos_parameters['Emin'] + self.ctx.nscf_fermi
            dos_parameters['DOS']['Emax'] = dos_parameters['Emax'] + self.ctx.nscf_fermi

        dos_inputs.parameters = orm.Dict(dict=dos_parameters)
        dos_inputs['metadata']['call_link_label'] = 'dos'
        return dos_inputs
Beispiel #4
0
    def run_pp(self):
        """Run the PwBaseWorkChain in scf mode on the primitive cell of (optionally relaxed) input structure."""
        inputs = AttributeDict(self.exposed_inputs(PpCalculation, namespace='pp'))
        inputs.metadata.call_link_label = 'pp'
        inputs.parent_folder = self.ctx.current_folder

        nscf_params = self.ctx.workchain_nscf.outputs.output_parameters

        inputs.parameters = inputs.parameters.get_dict()
        inputs.parameters.setdefault('INPUTPP', {})
        inputs.parameters.setdefault('PLOT', {})
        inputs.parameters['INPUTPP']['plot_num'] = 7
        nel = int(nscf_params['number_of_electrons'])
        if 'wavefunction_min' in self.inputs:
            kband_min = self.inputs.wavefunction_min.value
        else:
            if 'wavefunction_ef_min' in self.inputs:
                i = self.inputs.wavefunction_ef_min.value - 1
                kband_min = nel - i
            else:
                kband_min = 1

        if 'wavefunction_max' in self.inputs:
            kband_max = self.inputs.wavefunction_max.value
        else:
            if 'wavefunction_ef_max' in self.inputs:
                i = self.inputs.wavefunction_ef_max.value 
                kband_max = nel + i
            else:
                kband_max = nscf_params['number_of_atomic_wfc']

        inputs.parameters['INPUTPP']['kband(1)'] = kband_min
        inputs.parameters['INPUTPP']['kband(2)'] = kband_max
        inputs.parameters['INPUTPP']['kpoint(1)'] = 1
        inputs.parameters['INPUTPP']['kpoint(2)'] = nscf_params['number_of_k_points']

        inputs.parameters['PLOT']['iflag'] = 3
        # inputs.parameters['PLOT']['output_format'] = 5

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

        self.report(f'launching PpCalculation<{running.pk}>')

        return ToContext(workchain_pp=running)
Beispiel #5
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)