From 6f9d522b9e66e29f94cfb2032bd12d192f6a5759 Mon Sep 17 00:00:00 2001 From: janssenhenning Date: Fri, 14 Jan 2022 10:52:40 +0100 Subject: [PATCH 1/4] Add implementation of workchain and generator of CommonBandsWorkchain for the Fleur Code --- .../workflows/bands/fleur/__init__.py | 7 ++ .../workflows/bands/fleur/generator.py | 64 +++++++++++++++++++ .../workflows/bands/fleur/workchain.py | 34 ++++++++++ setup.json | 1 + 4 files changed, 106 insertions(+) create mode 100644 aiida_common_workflows/workflows/bands/fleur/__init__.py create mode 100644 aiida_common_workflows/workflows/bands/fleur/generator.py create mode 100644 aiida_common_workflows/workflows/bands/fleur/workchain.py diff --git a/aiida_common_workflows/workflows/bands/fleur/__init__.py b/aiida_common_workflows/workflows/bands/fleur/__init__.py new file mode 100644 index 00000000..c725bf86 --- /dev/null +++ b/aiida_common_workflows/workflows/bands/fleur/__init__.py @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- +# pylint: disable=undefined-variable +"""Module with the implementations of the common bands workchain for Siesta.""" +from .generator import * +from .workchain import * + +__all__ = (generator.__all__ + workchain.__all__) diff --git a/aiida_common_workflows/workflows/bands/fleur/generator.py b/aiida_common_workflows/workflows/bands/fleur/generator.py new file mode 100644 index 00000000..3fe0bb40 --- /dev/null +++ b/aiida_common_workflows/workflows/bands/fleur/generator.py @@ -0,0 +1,64 @@ +# -*- coding: utf-8 -*- +"""Implementation of `aiida_common_workflows.common.bands.generator.CommonBandsInputGenerator` for Fleur.""" + +from aiida import engine, orm + +from aiida_common_workflows.generators import CodeType + +from ..generator import CommonBandsInputGenerator + +__all__ = ('FleurCommonBandsInputGenerator',) + + +class FleurCommonBandsInputGenerator(CommonBandsInputGenerator): + """Generator of inputs for the FleurCommonBandsWorkChain""" + + @classmethod + def define(cls, spec): + """Define the specification of the input generator. + + The ports defined on the specification are the inputs that will be accepted by the ``get_builder`` method. + """ + super().define(spec) + spec.inputs['engines']['bands']['code'].valid_type = CodeType('fleur.fleur') + + def _construct_builder(self, **kwargs) -> engine.ProcessBuilder: + """Construct a process builder based on the provided keyword arguments. + + The keyword arguments will have been validated against the input generator specification. + """ + # pylint: disable=too-many-branches,too-many-statements,too-many-locals + engines = kwargs.get('engines', None) + parent_folder = kwargs['parent_folder'] + bands_kpoints = kwargs['bands_kpoints'] + + # From the parent folder, we retrieve the calculation that created it. + parent_calc = parent_folder.creator + if parent_calc.process_type != 'aiida.calculations:fleur.fleur': + raise ValueError('The `parent_folder` has not been created by a FleurCalculation') + builder_parent = parent_folder.creator.get_builder_restart() + + builder = self.process_class.get_builder() + builder.options = orm.Dict(dict=builder_parent.metadata.options) + builder.metadata = {} + for key, value in builder_parent.items(): + if value and key != 'metadata': + builder[key] = value + + wf_parameters = {'kpath': 'skip'} + + builder.wf_parameters = orm.Dict(dict=wf_parameters) + builder.kpoints = bands_kpoints + builder.remote = parent_folder + + if engines: + try: + band_engines = engines['bands'] + except KeyError: + raise ValueError('The `engines` dictionary must contain `bands` as a top-level key') + if 'code' in band_engines: + builder.code = band_engines['code'] + if 'options' in band_engines: + builder.options = orm.Dict(dict=band_engines['options']) + + return builder diff --git a/aiida_common_workflows/workflows/bands/fleur/workchain.py b/aiida_common_workflows/workflows/bands/fleur/workchain.py new file mode 100644 index 00000000..1b1d6ec3 --- /dev/null +++ b/aiida_common_workflows/workflows/bands/fleur/workchain.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +"""Implementation of `aiida_common_workflows.common.relax.workchain.CommonRelaxWorkChain` for Fleur.""" +from aiida.engine import calcfunction +from aiida.orm import Float +from aiida.plugins import WorkflowFactory + +from ..workchain import CommonBandsWorkChain +from .generator import FleurCommonBandsInputGenerator + +__all__ = ('FleurCommonBandsWorkChain',) + + +@calcfunction +def get_fermi_energy(pardict): + """Extract the Fermi energy from the `output_parameters` dictionary""" + return Float(pardict['fermi_energy_scf']) + + +class FleurCommonBandsWorkChain(CommonBandsWorkChain): + """Implementation of `aiida_common_workflows.common.bands.workchain.CommonBandsWorkChain` for Fleur.""" + + _process_class = WorkflowFactory('fleur.banddos') + _generator_class = FleurCommonBandsInputGenerator + + def convert_outputs(self): + """Convert the outputs of the sub workchain to the common output specification.""" + self.report('Bands calculation concluded sucessfully, converting outputs') + if 'output_banddos_wc_bands' not in self.ctx.workchain.outputs: + self.report('FleurBandDOSWorkChain concluded without returning bands!') + return self.exit_codes.ERROR_SUB_PROCESS_FAILED + + self.out('fermi_energy', get_fermi_energy(self.ctx.workchain.outputs.output_banddos_wc_para)) + + self.out('bands', self.ctx.workchain.outputs['output_banddos_wc_bands']) diff --git a/setup.json b/setup.json index 2f5fa85a..e0bfe878 100644 --- a/setup.json +++ b/setup.json @@ -74,6 +74,7 @@ "common_workflows.relax.quantum_espresso = aiida_common_workflows.workflows.relax.quantum_espresso.workchain:QuantumEspressoCommonRelaxWorkChain", "common_workflows.relax.siesta = aiida_common_workflows.workflows.relax.siesta.workchain:SiestaCommonRelaxWorkChain", "common_workflows.relax.vasp = aiida_common_workflows.workflows.relax.vasp.workchain:VaspCommonRelaxWorkChain", + "common_workflows.bands.fleur = aiida_common_workflows.workflows.bands.fleur.workchain:FleurCommonBandsWorkChain", "common_workflows.bands.siesta = aiida_common_workflows.workflows.bands.siesta.workchain:SiestaCommonBandsWorkChain" ] }, From 392fae6ab2098153cae370d6798989018f5beada Mon Sep 17 00:00:00 2001 From: janssenhenning Date: Fri, 14 Jan 2022 12:43:56 +0100 Subject: [PATCH 2/4] Fix wrong code input names --- aiida_common_workflows/workflows/bands/fleur/generator.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/aiida_common_workflows/workflows/bands/fleur/generator.py b/aiida_common_workflows/workflows/bands/fleur/generator.py index 3fe0bb40..511363a6 100644 --- a/aiida_common_workflows/workflows/bands/fleur/generator.py +++ b/aiida_common_workflows/workflows/bands/fleur/generator.py @@ -40,10 +40,7 @@ def _construct_builder(self, **kwargs) -> engine.ProcessBuilder: builder = self.process_class.get_builder() builder.options = orm.Dict(dict=builder_parent.metadata.options) - builder.metadata = {} - for key, value in builder_parent.items(): - if value and key != 'metadata': - builder[key] = value + builder.fleur = builder_parent.code wf_parameters = {'kpath': 'skip'} @@ -57,7 +54,7 @@ def _construct_builder(self, **kwargs) -> engine.ProcessBuilder: except KeyError: raise ValueError('The `engines` dictionary must contain `bands` as a top-level key') if 'code' in band_engines: - builder.code = band_engines['code'] + builder.fleur = band_engines['code'] if 'options' in band_engines: builder.options = orm.Dict(dict=band_engines['options']) From ca56a390840241f45c60b91dcd69a2873ffec65a Mon Sep 17 00:00:00 2001 From: janssenhenning Date: Fri, 14 Jan 2022 13:08:47 +0100 Subject: [PATCH 3/4] Correct the fermi energy output. The bands output of fleur is shifted to ef=0.0 --- .../workflows/bands/fleur/generator.py | 2 ++ .../workflows/bands/fleur/workchain.py | 9 ++------- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/aiida_common_workflows/workflows/bands/fleur/generator.py b/aiida_common_workflows/workflows/bands/fleur/generator.py index 511363a6..a477ea78 100644 --- a/aiida_common_workflows/workflows/bands/fleur/generator.py +++ b/aiida_common_workflows/workflows/bands/fleur/generator.py @@ -38,6 +38,7 @@ def _construct_builder(self, **kwargs) -> engine.ProcessBuilder: raise ValueError('The `parent_folder` has not been created by a FleurCalculation') builder_parent = parent_folder.creator.get_builder_restart() + #Transfer inputs from the parent calculation builder = self.process_class.get_builder() builder.options = orm.Dict(dict=builder_parent.metadata.options) builder.fleur = builder_parent.code @@ -48,6 +49,7 @@ def _construct_builder(self, **kwargs) -> engine.ProcessBuilder: builder.kpoints = bands_kpoints builder.remote = parent_folder + #Add inputs from engines if given if engines: try: band_engines = engines['bands'] diff --git a/aiida_common_workflows/workflows/bands/fleur/workchain.py b/aiida_common_workflows/workflows/bands/fleur/workchain.py index 1b1d6ec3..27730fe3 100644 --- a/aiida_common_workflows/workflows/bands/fleur/workchain.py +++ b/aiida_common_workflows/workflows/bands/fleur/workchain.py @@ -10,12 +10,6 @@ __all__ = ('FleurCommonBandsWorkChain',) -@calcfunction -def get_fermi_energy(pardict): - """Extract the Fermi energy from the `output_parameters` dictionary""" - return Float(pardict['fermi_energy_scf']) - - class FleurCommonBandsWorkChain(CommonBandsWorkChain): """Implementation of `aiida_common_workflows.common.bands.workchain.CommonBandsWorkChain` for Fleur.""" @@ -29,6 +23,7 @@ def convert_outputs(self): self.report('FleurBandDOSWorkChain concluded without returning bands!') return self.exit_codes.ERROR_SUB_PROCESS_FAILED - self.out('fermi_energy', get_fermi_energy(self.ctx.workchain.outputs.output_banddos_wc_para)) + #The bands output of fleur is shifted to have the fermi energy at zero + self.out('fermi_energy', Float(0.0)) self.out('bands', self.ctx.workchain.outputs['output_banddos_wc_bands']) From 401189b234e8727ed2fb48d21bdb70327f497be4 Mon Sep 17 00:00:00 2001 From: janssenhenning Date: Thu, 7 Apr 2022 10:30:53 +0200 Subject: [PATCH 4/4] Remove unused import --- aiida_common_workflows/workflows/bands/fleur/workchain.py | 1 - 1 file changed, 1 deletion(-) diff --git a/aiida_common_workflows/workflows/bands/fleur/workchain.py b/aiida_common_workflows/workflows/bands/fleur/workchain.py index 27730fe3..d4ec938c 100644 --- a/aiida_common_workflows/workflows/bands/fleur/workchain.py +++ b/aiida_common_workflows/workflows/bands/fleur/workchain.py @@ -1,6 +1,5 @@ # -*- coding: utf-8 -*- """Implementation of `aiida_common_workflows.common.relax.workchain.CommonRelaxWorkChain` for Fleur.""" -from aiida.engine import calcfunction from aiida.orm import Float from aiida.plugins import WorkflowFactory