Source code for aim2dat.aiida_workflows.cp2k.eigenvalues_work_chain

"""
Aiida work chains for cp2k to find parameters that converge the Kohn-Sham equations.
"""

# Third party library imports
import aiida.orm as aiida_orm
from aiida.engine import (
    process_handler,
    ExitCode,
)

# Internal library imports
from aim2dat.aiida_workflows.cp2k.base_core_work_chain import _BaseCoreWorkChain
from aim2dat.aiida_workflows.cp2k.core_work_chain_handlers import _switch_to_atomic_scf_guess
from aim2dat.utils.dict_tools import (
    dict_retrieve_parameter,
    dict_set_parameter,
    dict_create_tree,
)


[docs]class EigenvaluesWorkChain(_BaseCoreWorkChain): """ AiiDA work chain to calculate the band structure with cp2k. """ _keep_scf_method_fixed = True _keep_smearing_fixed = True _initial_scf_guess = "RESTART" @classmethod def define(cls, spec): """Specify inputs and outputs.""" super().define(spec) spec.input( "adjust_scf_parameters", valid_type=aiida_orm.Bool, default=lambda: aiida_orm.Bool(False), help="Restart calculation with adjusted parameters if SCF-clycles are not converged.", ) def setup_wc_specific_inputs(self): """Set k-points to full grid and the print statement.""" self.ctx.inputs.metadata.options.parser_name = "aim2dat.cp2k.standard" self.ctx.adj_kpoints = True self.ctx.always_add_unocc_states = True parameters = self.ctx.inputs.parameters.get_dict() # Add the print-command for eigenvalues: extra_sections = {"MO": {"EIGENVALUES": True, "EACH": {"QS_SCF": 1000}}} dict_create_tree(parameters, ["FORCE_EVAL", "DFT", "PRINT"]) parameters["FORCE_EVAL"]["DFT"]["PRINT"].update(extra_sections) # Change k-point parallelization to print all k-points: kpoints = dict_retrieve_parameter(parameters, ["FORCE_EVAL", "DFT", "KPOINTS"]) if kpoints is not None: dict_set_parameter(parameters, ["FORCE_EVAL", "DFT", "KPOINTS", "FULL_GRID"], False) dict_set_parameter( parameters, ["FORCE_EVAL", "DFT", "KPOINTS", "PARALLEL_GROUP_SIZE"], 0 ) self.ctx.inputs.parameters = aiida_orm.Dict(dict=parameters) self.ctx.inputs.settings = aiida_orm.Dict(dict={"output_check_scf_conv": True}) @process_handler( priority=402, exit_codes=ExitCode(0), ) def switch_to_atomic_scf_guess(self, calc): """ Switch to atomic guess for the case that the scf-cycles do not converge. """ return self._execute_error_handler(calc, _switch_to_atomic_scf_guess)