Esempio n. 1
0
    def run_bands(self):
        """
        Run the PwBaseWorkChain to run a bands PwCalculation along the path of high-symmetry determined by Seekpath
        """
        try:
            remote_folder = self.ctx.workchain_scf.out.remote_folder
        except AttributeError as exception:
            self.abort_nowait(
                'the scf workchain did not output a remote_folder node')
            return

        inputs = self.ctx.inputs
        restart_mode = 'restart'
        calculation_mode = 'bands'

        # Set the correct pw.x input parameters
        inputs.parameters['CONTROL']['restart_mode'] = restart_mode
        inputs.parameters['CONTROL']['calculation'] = calculation_mode

        if 'kpoints' in self.inputs:
            inputs.kpoints = self.inputs.kpoints
        else:
            inputs.kpoints = self.ctx.kpoints_path

        inputs.structure = self.ctx.structure
        inputs.parent_folder = remote_folder

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

        self.report('launching PwBaseWorkChain<{}> in {} mode'.format(
            running.pid, calculation_mode))

        return ToContext(workchain_bands=running)
Esempio n. 2
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)
Esempio n. 3
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)
Esempio n. 4
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)
Esempio n. 5
0
    def run_relax(self):
        """Run the `PwBaseWorkChain` to run a relax `PwCalculation`."""
        self.ctx.iteration += 1

        inputs = AttributeDict(self.exposed_inputs(PwBaseWorkChain, namespace='base'))
        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'] = self.inputs.relaxation_scheme.value
        inputs.pw.parameters['CONTROL']['restart_mode'] = 'from_scratch'

        # If one of the nested `PwBaseWorkChains` changed the number of bands, apply it here
        if self.ctx.current_number_of_bands is not None:
            inputs.pw.parameters.setdefault('SYSTEM', {})['nbnd'] = self.ctx.current_number_of_bands

        # Set the `CALL` link label
        inputs.metadata.call_link_label = 'iteration_{:02d}'.format(self.ctx.iteration)

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

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

        return ToContext(workchains=append_(running))
Esempio n. 6
0
    def run_calculation(self):
        """Run the next calculation, taking the input dictionary from the context at `self.ctx.inputs`."""
        from aiida_quantumespresso.utils.mapping import prepare_process_inputs

        self.ctx.iteration += 1

        try:
            unwrapped_inputs = self.ctx.inputs
        except AttributeError:
            raise AttributeError('no calculation input dictionary was defined in `self.ctx.inputs`')

        # Set the `CALL` link label
        unwrapped_inputs['metadata']['call_link_label'] = 'iteration_{:02d}'.format(self.ctx.iteration)

        inputs = prepare_process_inputs(self._calculation_class, unwrapped_inputs)
        calculation = self.submit(self._calculation_class, **inputs)

        # Add a new empty list to the `errors_handled` extra. If any errors handled registered through the
        # `register_error_handler` decorator return an `ErrorHandlerReport`, their name will be appended to that list.
        errors_handled = self.node.get_extra('errors_handled', [])
        errors_handled.append([])
        self.node.set_extra('errors_handled', errors_handled)

        self.report('launching {}<{}> iteration #{}'.format(self.ctx.calc_name, calculation.pk, self.ctx.iteration))

        return ToContext(calculations=append_(calculation))
Esempio n. 7
0
    def run_nscf(self):
        """Run an NSCF calculation, to generate eigenvalues with a denser k-point mesh.

        This calculation modifies the base scf calculation inputs by:

        - Using the parent folder from the scf calculation.
        - Replacing the kpoints, if an alternative is specified for nscf.
        - Changing ``SYSTEM.occupations`` to 'tetrahedra'.
        - Changing ``SYSTEM.nosym`` to True, to avoid generation of additional k-points in low symmetry cases.
        - Replace the ``pw.metadata.options``, if an alternative is specified for nscf.

        """
        inputs = AttributeDict(self.exposed_inputs(PwBaseWorkChain, 'nscf'))
        if 'scf' in self.inputs:
            inputs.pw.parent_folder = self.ctx.scf_parent_folder
        inputs.pw.structure = self.inputs.structure

        inputs.metadata.call_link_label = 'nscf'
        inputs = prepare_process_inputs(PwBaseWorkChain, inputs)

        if self.ctx.dry_run:
            return inputs

        future = self.submit(PwBaseWorkChain, **inputs)

        self.report(f'launching NSCF PwBaseWorkChain<{future.pk}>')

        return ToContext(workchain_nscf=future)
Esempio n. 8
0
    def run_relax(self):
        """Run the `PwBaseWorkChain` to run a relax `PwCalculation`."""
        self.ctx.iteration += 1

        inputs = AttributeDict(
            self.exposed_inputs(PwBaseWorkChain, namespace='base'))
        inputs.pw.structure = self.ctx.current_structure
        inputs.pw.parameters = inputs.pw.parameters.get_dict()

        inputs.pw.parameters.setdefault('CELL', {})
        inputs.pw.parameters.setdefault('CONTROL', {})
        inputs.pw.parameters['CONTROL']['restart_mode'] = 'from_scratch'

        if 'relaxation_scheme' in self.inputs:
            if self.inputs.relaxation_scheme.value == 'relax':
                relax_type = RelaxType.ATOMS
            elif self.inputs.relaxation_scheme.value == 'vc-relax':
                relax_type = RelaxType.ATOMS_CELL
            else:
                raise ValueError(
                    'unsupported value for the `relaxation_scheme` input.')
        else:
            relax_type = RelaxType(self.inputs.relax_type)

        if relax_type in [
                RelaxType.NONE, RelaxType.VOLUME, RelaxType.SHAPE,
                RelaxType.CELL
        ]:
            inputs.pw.settings = self._fix_atomic_positions(
                inputs.pw.structure, inputs.pw.get('settings', None))

        if relax_type in [RelaxType.NONE, RelaxType.ATOMS]:
            inputs.pw.parameters['CONTROL']['calculation'] = 'relax'
            inputs.pw.parameters.pop('CELL', None)
        else:
            inputs.pw.parameters['CONTROL']['calculation'] = 'vc-relax'

        if relax_type in [RelaxType.VOLUME, RelaxType.ATOMS_VOLUME]:
            inputs.pw.parameters['CELL']['cell_dofree'] = 'volume'

        if relax_type in [RelaxType.SHAPE, RelaxType.ATOMS_SHAPE]:
            inputs.pw.parameters['CELL']['cell_dofree'] = 'shape'

        if relax_type in [RelaxType.CELL, RelaxType.ATOMS_CELL]:
            inputs.pw.parameters['CELL']['cell_dofree'] = 'all'

        # If one of the nested `PwBaseWorkChains` changed the number of bands, apply it here
        if self.ctx.current_number_of_bands is not None:
            inputs.pw.parameters.setdefault(
                'SYSTEM', {})['nbnd'] = self.ctx.current_number_of_bands

        # Set the `CALL` link label
        inputs.metadata.call_link_label = f'iteration_{self.ctx.iteration:02d}'

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

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

        return ToContext(workchains=append_(running))
Esempio n. 9
0
    def calculate_trim_wf(self):
        """Launch a pw_bands calculation on the TRIM points for the structure."""
        self.report(
            'Using parities at TRIM points to calculatte Z2 invariant.')
        kpoints = generate_trim(self.ctx.current_structure,
                                self.inputs.dimensionality)

        inputs = AttributeDict(
            self.exposed_inputs(PwBaseWorkChain, namespace='band'))
        inputs.clean_workdir = self.inputs.clean_workdir
        inputs.pw.code = self.inputs.pw_code
        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'] = 'bands'
        inputs.pw.parent_folder = self.ctx.scf_folder
        inputs.kpoints = kpoints

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

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

        return ToContext(workchain_trim=running)
Esempio n. 10
0
 def _prepare_process_inputs(self, inputs):
     """
     Prepare the inputs dictionary for a calculation process. Any remaining bare dictionaries in the inputs
     dictionary will be wrapped in a ParameterData data node except for the '_options' key which should remain
     a standard dictionary. Another exception are dictionaries whose keys are not strings but for example tuples.
     This is the format used by input groups as in for example the explicit pseudo dictionary where the key is
     a tuple of kind to which the UpfData corresponds.
     """
     from aiida_quantumespresso.utils.mapping import prepare_process_inputs
     return prepare_process_inputs(inputs)
Esempio n. 11
0
    def run_dos_full(self):
        """Run the PwBaseWorkChain in bands mode along the path of high-symmetry determined by seekpath."""
        inputs = AttributeDict(self.exposed_inputs(DosCalc, namespace='dos_full'))
        inputs.metadata.call_link_label = 'dos_full'
        inputs.parent_folder = self.ctx.current_folder

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

        self.report('launching DosCalculation<{}> in {} mode for the FULL - CROP grid'.format(running.pk, 'dos'))

        return ToContext(workchain_dos_full=running)
Esempio n. 12
0
    def run_pw2gw(self):
        """Run the PwBaseWorkChain in bands mode along the path of high-symmetry determined by seekpath."""
        inputs = AttributeDict(self.exposed_inputs(Pw2gwCalc, namespace='pw2gw'))
        inputs.metadata.call_link_label = 'pw2gw'
        inputs.parent_folder = self.ctx.current_folder

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

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

        return ToContext(workchain_pw2gw=running)
Esempio n. 13
0
    def run_bands(self):
        """Run the band calculation."""
        self.ctx.iteration += 1
        inputs = self.ctx.inputs
        inputs.kpoints = self.ctx.current_kpoints

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

        self.report(
            'launching PwBaseWorkChain<{}> in {} mode, iteration {}'.format(
                running.pk, 'bands', self.ctx.iteration))

        return ToContext(workchain_bands=append_(running))
Esempio n. 14
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.metadata.call_link_label = 'scf'
        inputs.pw.structure = self.ctx.current_structure
        inputs.pw.parameters = inputs.pw.parameters.get_dict()
        inputs.pw.parameters.setdefault('CONTROL', {})['calculation'] = 'scf'

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

        self.report(f'launching PwBaseWorkChain<{running.pk}> in scf mode')

        return ToContext(workchain_scf=running)
Esempio n. 15
0
    def run_nscf_crop(self):
        """Run the PwBaseWorkChain in nscf mode along the path of high-symmetry determined by seekpath."""
        inputs = AttributeDict(self.exposed_inputs(PwBaseWorkChain, namespace='nscf_crop'))
        inputs.metadata.call_link_label = 'nscf_crop'
        # inputs.pw.metadata.options.max_wallclock_seconds *= 4
        # inputs.kpoints_distance = self.inputs.kpoints_distance
        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', {})

        # The following flags always have to be set in the parameters, regardless of what caller specified in the inputs
        inputs.pw.parameters['CONTROL']['calculation'] = 'nscf'

        inputs.pop('kpoints_distance', None)
        inputs.kpoints = self.ctx.kpoint_crop

        # Only set the following parameters if not directly explicitly defined in the inputs
        # inputs.pw.parameters['ELECTRONS'].setdefault('diagonalization', 'cg')
        # inputs.pw.parameters['ELECTRONS'].setdefault('diago_full_acc', True)

        # If `nbands_factor` is defined in the inputs we set the `nbnd` parameter
        if 'nbands_factor_crop' in self.inputs:
            factor = self.inputs.nbands_factor_crop.value
            parameters = self.ctx.workchain_scf.outputs.output_parameters.get_dict()
            if int(parameters['number_of_spin_components']) > 1:
                nspin_factor = 2
            else:
                nspin_factor = 1
            nbands = int(parameters['number_of_bands'])
            nelectron = int(parameters['number_of_electrons'])
            nbnd = max(
                int(0.5 * nelectron * nspin_factor * factor),
                int(0.5 * nelectron * nspin_factor) + 4 * nspin_factor,
                nbands)
            inputs.pw.parameters['SYSTEM']['nbnd'] = nbnd

        # Otherwise set the current number of bands, unless explicitly set in the inputs
        else:
            inputs.pw.parameters['SYSTEM'].setdefault('nbnd', self.ctx.current_number_of_bands)

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

        self.report('launching PwBaseWorkChain<{}> in {} mode for CROP grid'.format(running.pk, 'nscf'))

        return ToContext(workchain_nscf_crop=running)
    def run_final_scf(self):
        """Run the `PwBaseWorkChain` to run a final scf `PwCalculation` for the relaxed structure."""
        inputs = self.ctx.final_scf_inputs
        inputs.pw.structure = self.ctx.current_structure

        if self.ctx.current_number_of_bands is not None:
            inputs.pw.parameters.setdefault(
                'SYSTEM', {})['nbnd'] = self.ctx.current_number_of_bands

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

        self.report(f'launching PwBaseWorkChain<{running.pk}> for final scf')

        return ToContext(workchain_scf=running)
Esempio n. 17
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)
Esempio n. 18
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)
Esempio n. 19
0
    def run_scf(self):
        """Run an SCF calculation, to generate the wavefunction."""
        inputs = AttributeDict(self.exposed_inputs(PwBaseWorkChain, 'scf'))
        inputs.pw.structure = self.inputs.structure

        inputs.metadata.call_link_label = 'scf'
        inputs = prepare_process_inputs(PwBaseWorkChain, inputs)

        if self.ctx.dry_run:
            return inputs

        future = self.submit(PwBaseWorkChain, **inputs)

        self.report(f'launching SCF PwBaseWorkChain<{future.pk}>')

        return ToContext(workchain_scf=future)
Esempio n. 20
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)
Esempio n. 21
0
    def run_scf(self):
        """Run the PwBaseWorkChain in scf mode on the primitive cell of (optionally relaxed) input structure."""
        inputs = self._get_common_inputs()
        if not self.should_do_relax():
            self.ctx.current_structure = self.inputs.structure
        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.kpoints_distance = orm.Float(self.ctx.protocol['kpoints_mesh_density'])

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

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

        return ToContext(workchain_scf=running)
Esempio n. 22
0
    def run_scf(self):
        """Run the PwBaseWorkChain in scf mode on the input structure."""
        inputs = AttributeDict(
            self.exposed_inputs(PwBaseWorkChain, namespace='scf'))
        inputs.clean_workdir = self.inputs.clean_workdir
        inputs.pw.code = self.inputs.pw_code
        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('launching PwBaseWorkChain<{}> in {} mode'.format(
            running.pk, 'scf'))

        return ToContext(workchain_scf=running)
Esempio n. 23
0
    def first_bands_step(self):
        """Do a bandcalculation using the kpoints provided in `starting_kpoints`."""
        self.ctx.iteration += 1

        inputs = AttributeDict(deep_copy(self.ctx.inputs))
        inputs.kpoints = self.inputs.starting_kpoints

        try:
            kpt = inputs.kpoints.get_kpoints()
        except:
            kpt = inputs.kpoints.get_kpoints_mesh(print_list=True)
        nkpt = len(kpt)
        if 'settings' in inputs.pw:
            settings = inputs.pw.settings.get_dict()
            if 'cmdline' in settings:
                ptr = settings['cmdline']
                npools = None
                if '-npools' in ptr:
                    i = ptr.index('-npools')
                    npools = int(ptr[i + 1])
                elif '-nk' in ptr:
                    i = ptr.index('-nk')
                    npools = int(ptr[i + 1])

                if not npools is None and npools > nkpt:
                    self.report('WARNING: npools={} > nkpt={}'.format(
                        npools, nkpt))
                    for n in range(nkpt, 0, -1):
                        if npools % n == 0:
                            ptr[i + 1] = str(n)
                            self.report('... reducing npools to {}.'.format(n))
                            break

                inputs.pw.settings = settings

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

        self.report(
            'launching PwBaseWorkChain<{}> in {} mode, iteration {}'.format(
                running.pk, 'bands', self.ctx.iteration))

        return ToContext(workchain_bands=append_(running))
Esempio n. 24
0
    def run_scf(self):
        """
        Run the PwBaseWorkChain in scf mode on the primitive cell of (optionally relaxed) input structure
        """
        inputs = self.ctx.inputs
        calculation_mode = 'scf'

        # Set the correct pw.x input parameters
        inputs.parameters['CONTROL']['calculation'] = calculation_mode
        inputs.kpoints = self.ctx.kpoints_mesh
        inputs.structure = self.ctx.structure

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

        self.report('launching PwBaseWorkChain<{}> in {} mode'.format(
            running.pid, calculation_mode))

        return ToContext(workchain_scf=running)
Esempio n. 25
0
    def run_init(self):
        """Run an initialization `PwCalculation` that will exit after the preamble.

        In the preamble, all the relevant dimensions of the problem are computed which allows us to make an estimate of
        the required resources and what parallelization flags need to be set.
        """
        inputs = self.ctx.inputs

        # Set the initialization flag and the initial default options
        inputs.settings['ONLY_INITIALIZATION'] = True
        inputs.metadata['options'] = update_mapping(inputs.metadata['options'], get_default_options())

        # Prepare the final input dictionary
        inputs = prepare_process_inputs(PwCalculation, inputs)
        running = self.submit(PwCalculation, **inputs)

        self.report('launching initialization {}<{}>'.format(running.pk, self._process_class.__name__))

        return ToContext(calculation_init=running)
Esempio n. 26
0
    def run_final_scf(self):
        """Run the PwBaseWorkChain to run a final scf PwCalculation for the relaxed structure."""
        inputs = AttributeDict(
            self.exposed_inputs(PwBaseWorkChain, namespace='base'))
        inputs.structure = self.ctx.current_structure
        inputs.parent_folder = self.ctx.current_parent_folder
        inputs.parameters = inputs.parameters.get_dict()

        inputs.parameters.setdefault('CONTROL', {})
        inputs.parameters['CONTROL']['calculation'] = 'scf'
        inputs.parameters['CONTROL']['restart_mode'] = 'restart'

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

        self.report('launching PwBaseWorkChain<{}> for final scf'.format(
            running.pk))

        return ToContext(workchain_scf=running)
Esempio n. 27
0
    def run_nscf(self):
        """Run the PwBaseWorkChain in bands mode along the path of high-symmetry determined by seekpath."""
        inputs = AttributeDict(self.exposed_inputs(PwBaseWorkChain, namespace='nscf'))
        inputs.metadata.call_link_label = 'nscf'
        inputs.kpoints = self.ctx.bands_kpoints
        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', {})

        # The following flags always have to be set in the parameters, regardless of what caller specified in the inputs
        inputs.pw.parameters['CONTROL']['calculation'] = 'nscf'

        # Only set the following parameters if not directly explicitly defined in the inputs
        inputs.pw.parameters['ELECTRONS'].setdefault('diagonalization', 'cg')
        inputs.pw.parameters['ELECTRONS'].setdefault('diago_full_acc', True)

        # If `nbands_factor` is defined in the inputs we set the `nbnd` parameter
        factor = 1.2

        parameters = self.ctx.workchain_scf.outputs.output_parameters.get_dict()
        if int(parameters['number_of_spin_components']) > 1:
            nspin_factor = 2
        else:
            nspin_factor = 1
        nbands = int(parameters['number_of_bands'])
        nelectron = int(parameters['number_of_electrons'])
        nbnd = max(
            int(0.5 * nelectron * nspin_factor * factor),
            int(0.5 * nelectron * nspin_factor) + 4 * nspin_factor, nbands
        )
        inputs.pw.parameters['SYSTEM']['nbnd'] = nbnd
        inputs.pw.parameters['SYSTEM']['nosym'] = True

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

        self.report(f'launching PwBaseWorkChain<{running.pk}> in nscf mode')

        return ToContext(workchain_nscf=running)
Esempio n. 28
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.metadata.call_link_label = 'scf'
        inputs.pw.structure = self.ctx.current_structure
        inputs.pw.parameters = inputs.pw.parameters.get_dict()
        inputs.pw.parameters.setdefault('CONTROL', {})['calculation'] = 'scf'

        # Make sure to carry the number of bands from the relax workchain if it was run and it wasn't explicitly defined
        # in the inputs. One of the base workchains in the relax workchain may have changed the number automatically in
        #  the sanity checks on band occupations.
        if self.ctx.current_number_of_bands:
            inputs.pw.parameters.setdefault('SYSTEM', {}).setdefault('nbnd', self.ctx.current_number_of_bands)

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

        self.report(f'launching PwBaseWorkChain<{running.pk}> in scf mode')

        return ToContext(workchain_scf=running)
    def run_relax(self):
        """Run the `PwBaseWorkChain` to run a relax `PwCalculation`."""
        self.ctx.iteration += 1

        inputs = self.ctx.relax_inputs
        inputs.pw.structure = self.ctx.current_structure

        # If one of the nested `PwBaseWorkChains` changed the number of bands, apply it here
        if self.ctx.current_number_of_bands is not None:
            inputs.pw.parameters.setdefault(
                'SYSTEM', {})['nbnd'] = self.ctx.current_number_of_bands

        # Set the `CALL` link label
        inputs.metadata.call_link_label = f'iteration_{self.ctx.iteration:02d}'

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

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

        return ToContext(workchains=append_(running))
Esempio n. 30
0
    def setup_bands(self):
        """Set the inputs for the `bands` calculation."""
        inputs = AttributeDict(
            self.exposed_inputs(PwBaseWorkChain, namespace='bands'))

        inputs.pw.code = self.inputs.code
        inputs.kpoints = self.ctx.kpt_data

        inputs.pw.pseudos = self.inputs.pseudos
        inputs.pw.structure = self.inputs.structure
        inputs.pw.parent_folder = self.ctx.remote
        inputs.clean_workdir = self.inputs.clean_workdir

        inputs.pw.parameters = inputs.pw.parameters.get_dict()
        inputs.pw.parameters.setdefault('CONTROL', {})
        inputs.pw.parameters['CONTROL']['calculation'] = 'bands'
        inputs.pw.parameters['SYSTEM']['nosym'] = True

        inputs = prepare_process_inputs(PwBaseWorkChain, inputs)

        self.ctx.inputs = inputs