Source code for aim2dat.aiida_workflows.cp2k.cube_work_chain
"""
Aiida work chain for cp2k to calculate cube files.
"""
# 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_create_tree
_supported_cube_types = [
"efield",
"elf",
"external_potential",
"e_density",
"tot_density",
"v_hartree",
"v_xc",
]
def _validate_cube_types(value, _):
value = value.get_list()
if not all(val0 in _supported_cube_types for val0 in value):
return "Only '" + "', '".join(_supported_cube_types) + "' are supported cube types."
if len(set(value)) != len(value):
return "Field types cannot be calculated twice."
def _setup_wc_specific_inputs(ctx, inputs):
parameters = ctx.inputs.parameters.get_dict()
extra_sections = {}
for cube_type in inputs.cube_types.get_list():
extra_sections[cube_type.upper() + "_CUBE"] = {"STRIDE": 1}
dict_create_tree(parameters, ["FORCE_EVAL", "DFT", "PRINT"])
parameters["FORCE_EVAL"]["DFT"]["PRINT"].update(extra_sections)
ctx.inputs.parameters = aiida_orm.Dict(dict=parameters)
ctx.inputs.settings = aiida_orm.Dict(
dict={"additional_retrieve_temporary_list": ["*.cube"], "output_check_scf_conv": True}
)
[docs]class CubeWorkChain(_BaseCoreWorkChain):
"""
AiiDA work chain to calculate and store cube files using 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.",
)
spec.input(
"always_add_unocc_states",
valid_type=aiida_orm.Bool,
default=lambda: aiida_orm.Bool(False),
help="Always include some unoccupied states even if smearing is not used.",
)
spec.input(
"cube_types",
valid_type=aiida_orm.List,
validator=_validate_cube_types,
help="List of cubes that are calculated and stored.",
)
def setup_wc_specific_inputs(self):
"""Add print commands for the cube files."""
_setup_wc_specific_inputs(self.ctx, self.inputs)
@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)