예제 #1
0
    def run_pdos(self):
        """Run the `PdosWorkChain`."""
        inputs = AttributeDict(
            self.exposed_inputs(PdosWorkChain, namespace="pdos"))
        inputs.metadata.call_link_label = "pdos"
        inputs.structure = self.ctx.current_structure
        inputs.nscf.pw.parameters = inputs.nscf.pw.parameters.get_dict()

        if self.ctx.current_number_of_bands:
            inputs.nscf.pw.parameters.setdefault("SYSTEM", {}).setdefault(
                "nbnd", self.ctx.current_number_of_bands)

        if self.ctx.scf_parent_folder:
            inputs.pop("scf")
            inputs.nscf.pw.parent_folder = self.ctx.scf_parent_folder
        else:
            if "kpoints_distance_override" in self.inputs:
                inputs.scf.kpoints_distance = self.inputs.kpoints_distance_override

            if "degauss_override" in self.inputs:
                inputs.scf.pw.parameters = inputs.scf.pw.parameters.get_dict()
                inputs.scf.pw.parameters.setdefault(
                    "SYSTEM",
                    {})["degauss"] = self.inputs.degauss_override.value

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

        self.report(f"launching PdosWorkChain<{running.pk}>")

        return ToContext(workchain_pdos=running)
예제 #2
0
    def run_relax(self):
        """Run the `PwRelaxWorkChain`."""
        inputs = AttributeDict(
            self.exposed_inputs(PwRelaxWorkChain, namespace="relax"))
        inputs.metadata.call_link_label = "relax"
        inputs.structure = self.ctx.current_structure

        if "kpoints_distance_override" in self.inputs:
            inputs.base.kpoints_distance = self.inputs.kpoints_distance_override
            if "base_scf" in inputs:
                inputs.base_scf.kpoints_distance = self.inputs.kpoints_distance_override

        if "degauss_override" in self.inputs:
            inputs.base.pw.parameters = inputs.base.pw.parameters.get_dict()
            inputs.base.pw.parameters.setdefault(
                "SYSTEM", {})["degauss"] = self.inputs.degauss_override.value

            if "base_scf" in inputs:
                inputs.base_scf_params.pw.parameters = (
                    inputs.base_scf_params.pw.parameters.get_dict())
                inputs.base_scf_params.pw.parameters.setdefault(
                    "SYSTEM",
                    {})["degauss"] = self.inputs.degauss_override.value

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

        self.report(f"launching PwRelaxWorkChain<{running.pk}>")

        return ToContext(workchain_relax=running)
예제 #3
0
    def get_inputs_first_scf(self):
        """
        Initialize inputs for the first iteration.
        """
        input_scf = AttributeDict(
            self.exposed_inputs(FleurScfWorkChain, namespace='scf'))
        input_scf.metadata.label = 'SCF_forces'
        input_scf.metadata.description = 'The SCF workchain converging forces, part of the Relax'

        if self.ctx.wf_dict['break_symmetry']:
            calc_para = None
            if 'calc_parameters' in input_scf:
                calc_para = input_scf.calc_parameters
            # currently we always break the full symmetry
            break_dict = Dict(dict={'atoms': ['all']})  # for provenance
            broken_sys = break_symmetry_wf(input_scf.structure,
                                           wf_para=break_dict,
                                           parameterdata=calc_para)
            input_scf.structure = broken_sys['new_structure']
            input_scf.calc_parameters = broken_sys['new_parameters']

        if 'wf_parameters' not in input_scf:
            scf_wf_dict = {}
        else:
            scf_wf_dict = input_scf.wf_parameters.get_dict()

        if 'inpxml_changes' not in scf_wf_dict:
            scf_wf_dict['inpxml_changes'] = []

        scf_wf_dict['mode'] = 'force'

        if self.ctx.wf_dict['film_distance_relaxation']:
            scf_wf_dict['inpxml_changes'].append(('set_atomgr_att', {
                'attributedict': {
                    'force': [('relaxXYZ', 'FFT')]
                },
                'species': 'all'
            }))

        for specie_off in self.ctx.wf_dict['atoms_off']:
            scf_wf_dict['inpxml_changes'].append(('set_atomgr_att_label', {
                'attributedict': {
                    'force': [('relaxXYZ', 'FFF')]
                },
                'atom_label': specie_off
            }))

        scf_wf_dict['inpxml_changes'].append(('set_atomgr_att_label', {
            'attributedict': {
                'force': [('relaxXYZ', 'FFF')]
            },
            'atom_label': '49'
        }))

        input_scf.wf_parameters = Dict(dict=scf_wf_dict)

        return input_scf
예제 #4
0
    def run_relax(self):
        """Run the PwRelaxWorkChain to run a relax PwCalculation."""
        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)
예제 #5
0
    def run_relax(self):
        """Run the PwRelaxWorkChain to run a relax PwCalculation."""
        inputs = AttributeDict(self.exposed_inputs(PwRelaxWorkChain, namespace='relax'))
        inputs.metadata.call_link_label = 'relax'
        inputs.structure = self.ctx.current_structure

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

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

        return ToContext(workchain_relax=running)
예제 #6
0
    def run_find_crossings(self):
        """Run the FindCrossingsWorkChain to find bands crossings."""
        inputs = AttributeDict(
            self.exposed_inputs(FindCrossingsWorkChain, namespace='find'))
        inputs.structure = self.ctx.current_structure
        inputs.code = self.inputs.pw_code

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

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

        return ToContext(workchain_find=running)
예제 #7
0
    def prepare_z2pack(self):
        """Prepare the inputs for the z2pack calculations."""
        inputs = AttributeDict(
            self.exposed_inputs(Z2packBaseWorkChain, namespace='z2pack_base'))
        inputs.pw_code = self.inputs.pw_code
        inputs.structure = self.ctx.current_structure
        inputs.parent_folder = self.ctx.remote_scf

        self.ctx.inputs = inputs
        self.ctx.iteration = 0
        self.ctx.max_iteration = len(self.ctx.crossings)

        self.ctx.workchain_z2pack = []
예제 #8
0
    def prepare_eos(self):
        """
        Initialize inputs for eos workflow:
        wf_param, options, calculation parameters, codes, structure
        """
        inputs = AttributeDict(self.exposed_inputs(FleurEosWorkChain, namespace='eos'))
        inputs.metadata.label = 'EOS_substrate'
        inputs.metadata.description = 'The EOS workchain finding equilibrium substrate'
        # Here wf_dict nodes appears out of nowwhere.
        inputs.structure = create_substrate_bulk(Dict(dict=self.ctx.wf_dict))

        if not isinstance(inputs.structure, StructureData):
            return inputs, inputs.structure  # exit code thrown in create_substrate_bulk

        return inputs, None
예제 #9
0
    def prepare_z2pack(self):
        """Prepare the inputs for the z2ack calculation."""
        self.report('Using z2pack to calculatte Z2 invariant.')
        inputs = AttributeDict(
            self.exposed_inputs(Z2packBaseWorkChain, namespace='z2pack_base'))
        inputs.pw_code = self.inputs.pw_code
        inputs.structure = self.ctx.current_structure
        inputs.parent_folder = self.ctx.scf_folder

        settings = inputs.z2pack.z2pack_settings.get_dict()
        settings.update({
            'dimension_mode': '2D',
            'invariant': 'Z2',
        })

        self.ctx.inputs = inputs
예제 #10
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)