From 0b383f3d5e0ebbbf36bd4eca69feafbbd43a3515 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Philipp=20R=C3=BC=C3=9Fmann?=
Date: Mon, 30 Oct 2023 14:33:33 +0000
Subject: [PATCH 1/5] Expose initial_nonco_angles to kkrimp workchains
---
aiida_kkr/workflows/imp_BdG.py | 22 +++++++++++++++++++---
aiida_kkr/workflows/kkr_imp.py | 5 ++++-
aiida_kkr/workflows/kkr_imp_dos.py | 10 +++++++++-
aiida_kkr/workflows/kkr_imp_sub.py | 6 ++++++
4 files changed, 38 insertions(+), 5 deletions(-)
diff --git a/aiida_kkr/workflows/imp_BdG.py b/aiida_kkr/workflows/imp_BdG.py
index 872a0be6..f50bdc47 100644
--- a/aiida_kkr/workflows/imp_BdG.py
+++ b/aiida_kkr/workflows/imp_BdG.py
@@ -144,7 +144,7 @@ def define(cls, spec):
spec.expose_inputs(
kkr_imp_wc,
namespace='imp_scf',
- include=('startpot', 'wf_parameters', 'gf_writeout', 'scf.params_overwrite')
+ include=('startpot', 'wf_parameters', 'gf_writeout', 'scf.params_overwrite', 'scf.initial_noco_angles')
)
spec.inputs['imp_scf']['gf_writeout']['kkr'].required = False
spec.input('imp_scf.options', required=False, help='computer options for impurity scf step')
@@ -157,7 +157,11 @@ def define(cls, spec):
)
# inputs for impurity BdG scf
- spec.expose_inputs(kkr_imp_wc, namespace='BdG_scf', include=('startpot', 'remote_data_gf', 'gf_writeout'))
+ spec.expose_inputs(
+ kkr_imp_wc,
+ namespace='BdG_scf',
+ include=('startpot', 'remote_data_gf', 'gf_writeout', 'scf.initial_noco_angles')
+ )
spec.inputs['BdG_scf']['gf_writeout']['kkr'].required = False
spec.input('BdG_scf.options', required=False, help='computer options for BdG impurity scf step')
@@ -166,7 +170,11 @@ def define(cls, spec):
)
# inputs for impurity dos
- spec.expose_inputs(kkr_imp_dos_wc, namespace='dos', include=('wf_parameters', 'gf_dos_remote', 'gf_writeout'))
+ spec.expose_inputs(
+ kkr_imp_dos_wc,
+ namespace='dos',
+ include=('wf_parameters', 'gf_dos_remote', 'gf_writeout', 'initial_noco_angles')
+ )
spec.input(
'dos.gf_writeout.host_remote',
@@ -275,6 +283,8 @@ def imp_pot_calc(self):
builder.options = self.inputs.imp_scf.options
else:
builder.options = self.inputs.options
+ if 'initial_noco_angles' in self.inputs.imp_scf:
+ builder.scf.initial_noco_angles = self.inputs.imp_scf.initial_noco_angles
if 'gf_writeout' in self.inputs.imp_scf:
if 'options' in self.inputs.imp_scf.gf_writeout:
@@ -319,6 +329,8 @@ def imp_BdG_calc(self):
builder.params_kkr_overwrite = self.inputs.BdG_scf.gf_writeout.params_kkr_overwrite
if 'kkr' in self.inputs:
builder.gf_writeout.kkr = builder.kkr # pylint: disable=no-member
+ if 'initial_noco_angles' in self.inputs.BdG_scf:
+ builder.scf.initial_noco_angles = self.inputs.BdG_scf.initial_noco_angles
builder.remote_data_host = self.inputs.BdG_scf.remote_data_host
@@ -384,6 +396,10 @@ def DOS_calc(self):
else:
builder.options = self.inputs.options
+ # set nonco angles
+ if 'initial_noco_angles' in self.inputs.dos:
+ builder.initial_noco_angles = self.inputs.dos.initial_noco_angles
+
# skip BdG step and just use the starting potential instead?
# faster and same accuracy?!
if 'startpot' in self.inputs.BdG_scf:
diff --git a/aiida_kkr/workflows/kkr_imp.py b/aiida_kkr/workflows/kkr_imp.py
index 6ae94ed0..5be8edcf 100644
--- a/aiida_kkr/workflows/kkr_imp.py
+++ b/aiida_kkr/workflows/kkr_imp.py
@@ -101,7 +101,8 @@ def define(cls, spec):
# 'kkrimp',
'options',
# 'wf_parameters',
- 'params_overwrite'
+ 'params_overwrite',
+ 'initial_noco_angles'
)
)
@@ -793,6 +794,8 @@ def run_kkrimp_scf(self):
builder.params_overwrite = self.inputs.scf.params_overwrite
if 'options' in self.inputs.scf:
builder.options = self.inputs.scf.options
+ if 'initial_noco_angles' in self.inputs.scf:
+ builder.initial_noco_angles = self.inputs.scf.initial_noco_angles
builder.wf_parameters = kkrimp_params
future = self.submit(builder)
diff --git a/aiida_kkr/workflows/kkr_imp_dos.py b/aiida_kkr/workflows/kkr_imp_dos.py
index 2600ae0e..6a129d10 100644
--- a/aiida_kkr/workflows/kkr_imp_dos.py
+++ b/aiida_kkr/workflows/kkr_imp_dos.py
@@ -21,9 +21,12 @@
__copyright__ = (u'Copyright (c), 2019, Forschungszentrum Jülich GmbH, '
'IAS-1/PGI-1, Germany. All rights reserved.')
__license__ = 'MIT license, see LICENSE.txt file'
-__version__ = '0.6.13'
+__version__ = '0.6.14'
__contributors__ = (u'Fabian Bertoldo', u'Philipp Rüßmann')
+# activate verbose output, for debugging only
+_VERBOSE_ = True
+
#TODO: improve workflow output node structure
#TODO: generalise search for imp_info and conv_host from startpot
@@ -148,6 +151,7 @@ def define(cls, spec):
)
spec.expose_inputs(kkr_imp_sub_wc, namespace='BdG', include=('params_overwrite'))
+ spec.expose_inputs(kkr_imp_sub_wc, include=('initial_noco_angles'))
spec.expose_inputs(kkr_flex_wc, namespace='gf_writeout', include=('params_kkr_overwrite', 'options'))
# specify the outputs
@@ -206,6 +210,8 @@ def start(self):
"""
self.report(f'INFO: started KKR impurity DOS workflow version {self._workflowversion}')
+ if _VERBOSE_:
+ self.report(f'inputs: {self.inputs}')
# input both wf and options parameters
if 'wf_parameters' in self.inputs:
@@ -523,6 +529,8 @@ def run_imp_dos(self):
if 'params_overwrite' in self.inputs.BdG:
builder.params_overwrite = self.inputs.BdG.params_overwrite
+ if 'initial_noco_angles' in self.inputs:
+ builder.initial_noco_angles = self.inputs.initial_noco_angles
future = self.submit(builder)
diff --git a/aiida_kkr/workflows/kkr_imp_sub.py b/aiida_kkr/workflows/kkr_imp_sub.py
index ba80eb8a..02864c80 100644
--- a/aiida_kkr/workflows/kkr_imp_sub.py
+++ b/aiida_kkr/workflows/kkr_imp_sub.py
@@ -132,6 +132,8 @@ def define(cls, spec):
help='Dict of parameters that are given to the KKRimpCalculation. Overwrites automatically set values!'
)
+ spec.expose_inputs(KkrimpCalculation, include=('initial_noco_angles'))
+
# Here the structure of the workflow is defined
spec.outline(
cls.start,
@@ -862,6 +864,10 @@ def run_kkrimp(self):
if int(aiida_core_version.split('.')[0]) < 2 and self.ctx.do_final_cleanup:
inputs['cleanup_outfiles'] = Bool(self.ctx.do_final_cleanup)
+ # set nonco angles if given
+ if 'initial_noco_angles' in self.inputs:
+ inputs['initial_noco_angles'] = self.inputs.initial_noco_angles
+
# run the KKR calculation
message = 'INFO: doing calculation'
self.report(message)
From 40aefe23e473c696d3c2ad551a48d3a3d67d094f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Philipp=20R=C3=BC=C3=9Fmann?=
Date: Mon, 30 Oct 2023 16:03:52 +0000
Subject: [PATCH 2/5] Fix pre-commit
---
aiida_kkr/workflows/imp_BdG.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/aiida_kkr/workflows/imp_BdG.py b/aiida_kkr/workflows/imp_BdG.py
index f50bdc47..6f695b94 100644
--- a/aiida_kkr/workflows/imp_BdG.py
+++ b/aiida_kkr/workflows/imp_BdG.py
@@ -284,7 +284,7 @@ def imp_pot_calc(self):
else:
builder.options = self.inputs.options
if 'initial_noco_angles' in self.inputs.imp_scf:
- builder.scf.initial_noco_angles = self.inputs.imp_scf.initial_noco_angles
+ builder.scf.initial_noco_angles = self.inputs.imp_scf.initial_noco_angles # pylint: disable=no-member
if 'gf_writeout' in self.inputs.imp_scf:
if 'options' in self.inputs.imp_scf.gf_writeout:
@@ -330,7 +330,7 @@ def imp_BdG_calc(self):
if 'kkr' in self.inputs:
builder.gf_writeout.kkr = builder.kkr # pylint: disable=no-member
if 'initial_noco_angles' in self.inputs.BdG_scf:
- builder.scf.initial_noco_angles = self.inputs.BdG_scf.initial_noco_angles
+ builder.scf.initial_noco_angles = self.inputs.BdG_scf.initial_noco_angles # pylint: disable=no-member
builder.remote_data_host = self.inputs.BdG_scf.remote_data_host
From 9fb8babf5d491064b45652055e04991cea1b55e6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Philipp=20R=C3=BC=C3=9Fmann?=
Date: Tue, 31 Oct 2023 12:10:48 +0000
Subject: [PATCH 3/5] Remove deprecated cleanup option for KKRimp
---
aiida_kkr/calculations/kkrimp.py | 9 +-
aiida_kkr/parsers/kkr.py | 20 +---
aiida_kkr/parsers/kkrimp.py | 91 +----------------
aiida_kkr/workflows/kkr_imp.py | 30 +-----
aiida_kkr/workflows/kkr_imp_dos.py | 34 +------
aiida_kkr/workflows/kkr_imp_sub.py | 152 +----------------------------
6 files changed, 9 insertions(+), 327 deletions(-)
diff --git a/aiida_kkr/calculations/kkrimp.py b/aiida_kkr/calculations/kkrimp.py
index 17fe0b82..c41dd17d 100644
--- a/aiida_kkr/calculations/kkrimp.py
+++ b/aiida_kkr/calculations/kkrimp.py
@@ -22,7 +22,7 @@
__copyright__ = (u'Copyright (c), 2018, Forschungszentrum Jülich GmbH, '
'IAS-1/PGI-1, Germany. All rights reserved.')
__license__ = 'MIT license, see LICENSE.txt file'
-__version__ = '0.8.2'
+__version__ = '0.9.0'
__contributors__ = (u'Philipp Rüßmann', u'Fabian Bertoldo')
#TODO: implement 'ilayer_center' consistency check
@@ -171,13 +171,6 @@ def define(cls, spec):
Note: The length of the theta, phi and fix_dir lists have to be equal to the number of atoms in the impurity cluster.
"""
)
- spec.input(
- 'cleanup_outfiles',
- valid_type=Bool,
- required=False,
- default=lambda: Bool(False),
- help='Cleanup and compress output (works only in aiida-core<2.0 and breaks caching ability).'
- )
# define outputs
spec.output('output_parameters', valid_type=Dict, required=True, help='results of the KKRimp calculation')
diff --git a/aiida_kkr/parsers/kkr.py b/aiida_kkr/parsers/kkr.py
index 663b68b7..e1203dec 100644
--- a/aiida_kkr/parsers/kkr.py
+++ b/aiida_kkr/parsers/kkr.py
@@ -18,7 +18,7 @@
__copyright__ = (u'Copyright (c), 2017, Forschungszentrum Jülich GmbH, '
'IAS-1/PGI-1, Germany. All rights reserved.')
__license__ = 'MIT license, see LICENSE.txt file'
-__version__ = '0.7.0'
+__version__ = '0.8.0'
__contributors__ = ('Jens Broeder', u'Philipp Rüßmann')
@@ -229,21 +229,3 @@ def parse(self, debug=False, **kwargs):
if not success:
return self.exit_codes.ERROR_KKR_PARSING_FAILED
- else: # cleanup after parsing (only if parsing was successful)
- # cleanup only works below aiida-core v2.0
- if int(aiida_core_version.split('.')[0]) < 2:
- # delete completely parsed output files
- self.remove_unnecessary_files()
- # then (maybe) tar the output to save space
- # TODO needs implementing (see kkrimp parser)
-
- def remove_unnecessary_files(self):
- """
- Remove files that are not needed anymore after parsing
- The information is completely parsed (i.e. in outdict of calculation)
- and keeping the file would just be a duplication.
- """
- files_to_delete = [KkrCalculation._POTENTIAL, KkrCalculation._SHAPEFUN]
- for fileid in files_to_delete:
- if fileid in self.retrieved.list_object_names():
- self.retrieved.delete_object(fileid, force=True)
diff --git a/aiida_kkr/parsers/kkrimp.py b/aiida_kkr/parsers/kkrimp.py
index d3d40a4c..64fe4e89 100644
--- a/aiida_kkr/parsers/kkrimp.py
+++ b/aiida_kkr/parsers/kkrimp.py
@@ -21,7 +21,7 @@
__copyright__ = (u'Copyright (c), 2018, Forschungszentrum Jülich GmbH, '
'IAS-1/PGI-1, Germany. All rights reserved.')
__license__ = 'MIT license, see LICENSE.txt file'
-__version__ = '0.5.0'
+__version__ = '0.6.0'
__contributors__ = ('Philipp Rüßmann')
@@ -42,7 +42,7 @@ def __init__(self, calc):
# pylint: disable=protected-access
- def parse(self, debug=False, **kwargs):
+ def parse(self, debug=False, ignore_nan=False, **kwargs):
"""
Parse output data folder, store results in database.
@@ -113,7 +113,7 @@ def parse(self, debug=False, **kwargs):
# now we can parse the output files
success, msg_list, out_dict = KkrimpParserFunctions().parse_kkrimp_outputfile(
- out_dict, named_file_handles, debug=debug
+ out_dict, named_file_handles, debug=debug, ignore_nan=ignore_nan
)
out_dict['parser_errors'] = msg_list
@@ -132,22 +132,7 @@ def parse(self, debug=False, **kwargs):
# create output node and link
self.out('output_parameters', Dict(dict=out_dict))
- # cleanup after parsing (only if parsing was successful), only works below aiida-core v2.0
- if success:
- if int(aiida_core_version.split('.')[0]) < 2:
- # check if we should do the cleanup or not
- cleanup_outfiles = False
- if 'cleanup_outfiles' in self.node.inputs:
- cleanup_outfiles = self.node.inputs.cleanup_outfiles.value
- if cleanup_outfiles:
- # reduce size of timing file
- self.cleanup_outfiles(files['out_timing'], ['Iteration number', 'time until scf starts'])
- # reduce size of out_log file
- self.cleanup_outfiles(files['out_log'], ['Iteration Number'])
- # delete completely parsed output files and create a tar ball to reduce size
- self.remove_unnecessary_files()
- self.final_cleanup()
- else:
+ if not success:
return self.exit_codes.ERROR_PARSING_KKRIMPCALC
def _check_file_existance(self, files, keyname, fname, icrit, file_errors):
@@ -168,71 +153,3 @@ def _check_file_existance(self, files, keyname, fname, icrit, file_errors):
raise ValueError('icrit should be either 1 or 2')
file_errors.append((icrit, crit_level + f" File '{fname}' not found."))
files[keyname] = None
-
- def cleanup_outfiles(self, fileidentifier, keyslist):
- """open file and remove unneeded output"""
- if fileidentifier is not None:
- lineids = []
- with self.retrieved.open(fileidentifier) as tfile:
- txt = tfile.readlines()
- for iline in range(len(txt)):
- for key in keyslist: # go through all keys
- if key in txt[iline]: # add line id to list if key has been found
- lineids.append(iline)
- # rewrite file deleting the middle part
- if len(lineids) > 1: # cut only if more than one iteration was found
- txt = txt[:lineids[0]] + \
- ['# ... [removed output except for last iteration] ...\n'] + \
- txt[lineids[-1]:]
- with self.retrieved.open(fileidentifier, 'w') as tfilenew:
- tfilenew.writelines(txt)
-
- def remove_unnecessary_files(self):
- """
- Remove files that are not needed anymore after parsing
- The information is completely parsed (i.e. in outdict of calculation)
- and keeping the file would just be a duplication.
- """
- # first delete unused files (completely in parsed output)
- files_to_delete = [
- KkrimpCalculation._OUT_ENERGYSP_PER_ATOM, KkrimpCalculation._OUT_ENERGYTOT_PER_ATOM,
- KkrimpCalculation._SHAPEFUN
- ]
- for fileid in files_to_delete:
- if fileid in self.retrieved.list_object_names():
- self.retrieved.delete_object(fileid, force=True)
-
- def final_cleanup(self):
- """Create a tarball of the rest."""
-
- # short name for retrieved folder
- ret = self.retrieved
-
- # Now create tarball of output
- #
- # check if output has been packed to tarfile already
- # only if tarfile is not there we create the output tar file
- if KkrimpCalculation._FILENAME_TAR not in ret.list_object_names():
- # first create dummy file which is used to extract the full path that is given to tarfile.open
- with ret.open(KkrimpCalculation._FILENAME_TAR, 'w') as f:
- filepath_tar = f.name
-
- # now create tarfile and loop over content of retrieved directory
- to_delete = []
- with tarfile.open(filepath_tar, 'w:gz') as tf:
- for f in ret.list_object_names():
- with ret.open(f) as ftest:
- filesize = os.stat(ftest.name).st_size
- ffull = ftest.name
- if (
- f != KkrimpCalculation._FILENAME_TAR # ignore tar file
- and filesize > 0 # ignore empty files
- # ignore files starting with '.' like '.nfs...'
- and f[0] != '.'
- ):
- tf.add(ffull, arcname=os.path.basename(ffull))
- to_delete.append(f)
-
- # finally delete files that have been added to tarfile
- for f in to_delete:
- ret.delete_object(f, force=True)
diff --git a/aiida_kkr/workflows/kkr_imp.py b/aiida_kkr/workflows/kkr_imp.py
index 5be8edcf..f5583a56 100644
--- a/aiida_kkr/workflows/kkr_imp.py
+++ b/aiida_kkr/workflows/kkr_imp.py
@@ -13,7 +13,7 @@
from aiida_kkr.tools import test_and_get_codenode, neworder_potential_wf, update_params_wf
from aiida_kkr.workflows.gf_writeout import kkr_flex_wc
from aiida_kkr.workflows.voro_start import kkr_startpot_wc
-from aiida_kkr.workflows.kkr_imp_sub import kkr_imp_sub_wc, clean_sfd
+from aiida_kkr.workflows.kkr_imp_sub import kkr_imp_sub_wc
import numpy as np
from aiida_kkr.tools.save_output_nodes import create_out_dict_node
@@ -339,7 +339,6 @@ def start(self):
self.ctx.hfield = wf_dict.get('hfield', self._wf_default['hfield'])
self.ctx.init_pos = wf_dict.get('init_pos', self._wf_default['init_pos'])
self.ctx.accuracy_params = wf_dict.get('accuracy_params', self._wf_default['accuracy_params'])
- self.ctx.do_final_cleanup = wf_dict.get('do_final_cleanup', self._wf_default['do_final_cleanup'])
# set up new parameter dict to pass to kkrimp subworkflow later
self.ctx.kkrimp_params_dict = Dict({
'nsteps': self.ctx.nsteps,
@@ -355,15 +354,11 @@ def start(self):
'hfield': self.ctx.hfield,
'init_pos': self.ctx.init_pos,
'accuracy_params': self.ctx.accuracy_params,
- 'do_final_cleanup': self.ctx.do_final_cleanup
})
# retrieve option for kkrlfex files
self.ctx.retrieve_kkrflex = wf_dict.get('retrieve_kkrflex', self._wf_default['retrieve_kkrflex'])
- # list of things that are cleaned if everything ran through
- self.ctx.sfd_final_cleanup = []
-
# report the chosen parameters to the user
self.report(
'INFO: use the following parameter:\n'
@@ -739,8 +734,6 @@ def construct_startpot(self):
# add starting potential for kkrimp calculation to context
self.ctx.startpot_kkrimp = startpot_kkrimp
- # add to list for final cleanup
- self.ctx.sfd_final_cleanup.append(startpot_kkrimp)
self.report(
'INFO: created startpotential (pid: {}) for the impurity calculation '
@@ -856,10 +849,6 @@ def return_results(self):
self.out('converged_potential', self.ctx.kkrimp_scf_sub.outputs.host_imp_pot)
self.out('remote_data_gf', self.ctx.gf_remote)
- # cleanup things that are not needed anymore
- if self.ctx.do_final_cleanup:
- self.final_cleanup()
-
# print final message before exiting
self.report('INFO: created 3 output nodes for the KKR impurity workflow.')
self.report(
@@ -872,23 +861,6 @@ def return_results(self):
self.report(self.exit_codes.ERROR_KKRIMP_SUB_WORKFLOW_FAILURE) # pylint: disable=no-member
return self.exit_codes.ERROR_KKRIMP_SUB_WORKFLOW_FAILURE # pylint: disable=no-member
- def final_cleanup(self):
- """
- Remove unneeded files to save space
- """
- for sfd in self.ctx.sfd_final_cleanup:
- clean_sfd(sfd)
- if self.ctx.create_startpot:
- kkr_startpot = self.ctx.last_voro_calc
- vorocalc = kkr_startpot.outputs.last_voronoi_remote.get_incoming(link_label_filter=u'remote_folder'
- ).first().node
- ret = vorocalc.outputs.retrieved
- for fname in ret.list_object_names():
- if fname not in [VoronoiCalculation._OUTPUT_FILE_NAME, VoronoiCalculation._OUT_POTENTIAL_voronoi]:
- # delete all except vor default output file
- with ret.open(fname) as f:
- ret.delete_object(fname, force=True)
-
def error_handler(self):
"""Capture errors raised in validate_input"""
if self.ctx.exit_code is not None:
diff --git a/aiida_kkr/workflows/kkr_imp_dos.py b/aiida_kkr/workflows/kkr_imp_dos.py
index 6a129d10..0e72914d 100644
--- a/aiida_kkr/workflows/kkr_imp_dos.py
+++ b/aiida_kkr/workflows/kkr_imp_dos.py
@@ -21,7 +21,7 @@
__copyright__ = (u'Copyright (c), 2019, Forschungszentrum Jülich GmbH, '
'IAS-1/PGI-1, Germany. All rights reserved.')
__license__ = 'MIT license, see LICENSE.txt file'
-__version__ = '0.6.14'
+__version__ = '0.7.0'
__contributors__ = (u'Fabian Bertoldo', u'Philipp Rüßmann')
# activate verbose output, for debugging only
@@ -63,7 +63,6 @@ class kkr_imp_dos_wc(WorkChain):
} # execute KKR with mpi or without
_wf_default = {
- 'clean_impcalc_retrieved': True, # remove output of KKRimp calculation after successful parsing of DOS files
'jij_run': False, # calculate Jij's energy resolved
'lmdos': False, # calculate also (l,m) or only l-resolved DOS
'retrieve_kkrflex': True, # retrieve kkrflex files to repository or leave on remote computer only
@@ -254,10 +253,6 @@ def start(self):
if k not in self.ctx.dos_params_dict.keys():
self.ctx.dos_params_dict[k] = v
- self.ctx.cleanup_impcalc_output = wf_dict.get(
- 'clean_impcalc_retrieved', self._wf_default['clean_impcalc_retrieved']
- )
-
# set workflow parameters for the KKR impurity calculation
self.ctx.jij_run = wf_dict.get('jij_run', self._wf_default['jij_run'])
@@ -493,7 +488,6 @@ def run_imp_dos(self):
'dos_run': True,
'lmdos': self.ctx.lmdos,
'jij_run': self.ctx.jij_run,
- 'do_final_cleanup': self.ctx.cleanup_impcalc_output
})
kkrimp_params = self.ctx.kkrimp_params_dict
label_imp = 'KKRimp DOS (GF: {}, imp_pot: {}, Zimp: {}, ilayer_cent: {})'.format(
@@ -602,13 +596,6 @@ def return_results(self):
if self.ctx.lmdos:
self.out('dos_data_lm', dosXyDatas['dos_data_lm'])
self.out('dos_data_interpol_lm', dosXyDatas['dos_data_interpol_lm'])
- # maybe cleanup retrieved folder of DOS calculation
- if self.ctx.cleanup_impcalc_output:
- message = 'INFO: cleanup after storing of DOS data'
- print(message)
- self.report(message)
- pk_impcalc = self.ctx.kkrimp_dos.outputs.workflow_info['pks_all_calcs'][0]
- cleanup_kkrimp_retrieved(pk_impcalc)
message = f'INFO: workflow_info node: {outputnode_t.uuid}'
print(message)
@@ -799,22 +786,3 @@ def parse_impdosfiles(folder, natom, nspin, ef, use_lmdos):
output = {'dos_data': dosnode, 'dos_data_interpol': dosnode2}
return output
-
-
-def cleanup_kkrimp_retrieved(pk_impcalc):
- """
- remove output_all.tar.gz from retrieved of impurity calculation identified by pk_impcalc
- """
- from aiida.orm import load_node
- from aiida_kkr.calculations import KkrimpCalculation
-
- # extract retrieved folder
- doscalc = load_node(pk_impcalc)
- ret = doscalc.outputs.retrieved
-
- # name of tarfile
- tfname = KkrimpCalculation._FILENAME_TAR
-
- # remove tarfile from retreived dir
- if tfname in ret.list_object_names():
- ret.delete_object(tfname, force=True)
diff --git a/aiida_kkr/workflows/kkr_imp_sub.py b/aiida_kkr/workflows/kkr_imp_sub.py
index 02864c80..4f7f8a3b 100644
--- a/aiida_kkr/workflows/kkr_imp_sub.py
+++ b/aiida_kkr/workflows/kkr_imp_sub.py
@@ -17,7 +17,7 @@
__copyright__ = (u'Copyright (c), 2017, Forschungszentrum Jülich GmbH, '
'IAS-1/PGI-1, Germany. All rights reserved.')
__license__ = 'MIT license, see LICENSE.txt file'
-__version__ = '0.9.4'
+__version__ = '0.10.0'
__contributors__ = (u'Fabian Bertoldo', u'Philipp Ruessmann')
#TODO: work on return results function
@@ -82,8 +82,6 @@ class kkr_imp_sub_wc(WorkChain):
False, # specify if DOS should be calculated (!KKRFLEXFILES with energy contour necessary as GF_remote_data!)
'lmdos': True, # specify if DOS calculation should calculate l-resolved or l and m resolved output
'jij_run': False, # specify if Jijs should be calculated (!changes behavior of the code!!!)
- 'do_final_cleanup':
- True, # decide whether or not to clean up intermediate files (THIS BREAKS CACHABILITY!) # TODO: remove for aiida-core>2
# # Some parameter for direct solver (if None, use the same as in host code, otherwise overwrite)
'accuracy_params': {
'RADIUS_LOGPANELS': None, # where to set change of logarithmic to linear radial mesh
@@ -231,8 +229,6 @@ def start(self):
self.ctx.last_remote = None
# link to previous host impurity potential
self.ctx.last_pot = None
- # intermediate single file data objects that contain potential files which can be clean up at the end
- self.ctx.sfd_pot_to_clean = []
# convergence info about rms etc. (used to determine convergence behavior)
self.ctx.last_rms_all = []
self.ctx.rms_all_steps = []
@@ -255,9 +251,6 @@ def start(self):
message = 'INFO: using default wf parameter'
self.report(message)
- # cleanup intermediate calculations (WARNING: THIS PREVENTS USING CACHING!!!)
- self.ctx.do_final_cleanup = wf_dict.get('do_final_cleanup', self._wf_default['do_final_cleanup'])
-
# set option parameters from input, or defaults
self.ctx.withmpi = options_dict.get('withmpi', self._options_default['withmpi'])
self.ctx.resources = options_dict.get('resources', self._options_default['resources'])
@@ -767,7 +760,6 @@ def run_kkrimp(self):
emin = GF_out_params.get_dict().get('energy_contour_group').get('emin')
# then use this value to get rid of all core states that are lower than emin (return the same input potential if no states have been removed
imp_pot = kick_out_corestates_wf(imp_pot, Float(emin))
- self.ctx.sfd_pot_to_clean.append(imp_pot)
if 'impurity_info' in self.inputs:
message = 'INFO: using impurity_info node as input for kkrimp calculation'
self.report(message)
@@ -860,9 +852,6 @@ def run_kkrimp(self):
# add LDA+U input node if it was set in parent calculation of last kkrimp_remote or from input port
if self.ctx.settings_LDAU is not None:
inputs['settings_LDAU'] = self.ctx.settings_LDAU
- # set cleanup option
- if int(aiida_core_version.split('.')[0]) < 2 and self.ctx.do_final_cleanup:
- inputs['cleanup_outfiles'] = Bool(self.ctx.do_final_cleanup)
# set nonco angles if given
if 'initial_noco_angles' in self.inputs:
@@ -901,7 +890,6 @@ def inspect_kkrimp(self):
retrieved_folder = self.ctx.kkr.outputs.retrieved
imp_pot_sfd = extract_imp_pot_sfd(retrieved_folder)
self.ctx.last_pot = imp_pot_sfd
- self.ctx.sfd_pot_to_clean.append(self.ctx.last_pot)
print('use potfile sfd:', self.ctx.last_pot)
except:
message = 'ERROR: no output potential found'
@@ -1205,19 +1193,6 @@ def return_results(self):
"""
self.report(message)
- # cleanup of unnecessary files after convergence
- # WARNING: THIS DESTROYS CACHABILITY OF THE WORKFLOW!!!
- if self.ctx.do_final_cleanup:
- if self.ctx.successful:
- self.report('INFO: clean output of calcs')
- remove_out_pot_impcalcs(self.ctx.successful, all_pks)
- self.report('INFO: clean up raw_input folders')
- clean_raw_input(self.ctx.successful, all_pks)
-
- # clean intermediate single file data which are not needed after successful run or after DOS run
- if self.ctx.successful or self.ctx.dos_run:
- self.final_cleanup()
-
self.report('INFO: done with kkr_scf workflow!\n')
def error_handler(self):
@@ -1225,17 +1200,6 @@ def error_handler(self):
if self.ctx.exit_code is not None:
return self.ctx.exit_code
- def final_cleanup(self):
- uuid_last_calc = self.ctx.last_pot.uuid
- if not self.ctx.dos_run:
- sfds_to_clean = [i for i in self.ctx.sfd_pot_to_clean if i.uuid != uuid_last_calc]
- else:
- # in case of DOS run we can also clean the last output sfd file since this is never used
- sfds_to_clean = self.ctx.sfd_pot_to_clean
- # now clean all sfd files that are not needed anymore
- for sfd_to_clean in sfds_to_clean:
- clean_sfd(sfd_to_clean)
-
def _overwrite_parameters_from_input(self, new_params):
"""Overwrite input parameters for KKRimpCalculation if found in input"""
params_overwrite = self.inputs.params_overwrite.get_dict()
@@ -1248,120 +1212,6 @@ def _overwrite_parameters_from_input(self, new_params):
new_params[key] = val
-def remove_out_pot_impcalcs(successful, pks_all_calcs, dry_run=False):
- """
- Remove out_potential file from all but the last KKRimp calculation if workflow was successful
-
- Usage::
-
- imp_wf = load_node(266885) # maybe start with outer workflow
- pk_imp_scf = imp_wf.outputs.workflow_info['used_subworkflows'].get('kkr_imp_sub')
- imp_scf_wf = load_node(pk_imp_scf) # this is now the imp scf sub workflow
- successful = imp_scf_wf.outputs.workflow_info['successful']
- pks_all_calcs = imp_scf_wf.outputs.workflow_info['pks_all_calcs']
- """
- import tarfile, os
- from aiida.orm import load_node
- from aiida.common.folders import SandboxFolder
- from aiida_kkr.calculations import KkrimpCalculation
-
- if dry_run:
- print('test', successful, len(pks_all_calcs))
-
- # name of tarfile
- tfname = KkrimpCalculation._FILENAME_TAR
-
- # cleanup only if calculation was successful
- if successful and len(pks_all_calcs) > 1:
- # remove out_potential for calculations
- # note that also last calc can be cleaned since output potential is stored in single file data
- pks_for_cleanup = pks_all_calcs[:]
-
- # loop over all calculations
- for pk in pks_for_cleanup:
- if dry_run:
- print('pk_for_cleanup:', pk)
- # get getreived folder of calc
- calc = load_node(pk)
- ret = calc.outputs.retrieved
-
- # open tarfile if present
- if tfname in ret.list_object_names():
- delete_and_retar = False
- with ret.open(tfname) as tf:
- tf_abspath = tf.name
-
- # create Sandbox folder which is used to temporarily extract output_all.tar.gz
- tmpfolder = SandboxFolder()
- tmpfolder_path = tmpfolder.abspath
- with tarfile.open(tf_abspath) as tf:
- tar_filenames = [ifile.name for ifile in tf.getmembers()]
- # check if out_potential is in tarfile
- if KkrimpCalculation._OUT_POTENTIAL in tar_filenames:
- tf.extractall(tmpfolder_path)
- delete_and_retar = True
-
- if delete_and_retar and not dry_run:
- # delete out_potential
- os.remove(os.path.join(tmpfolder_path, KkrimpCalculation._OUT_POTENTIAL))
- with tarfile.open(tf_abspath, 'w:gz') as tf:
- # remove out_potential from list of files
- tar_filenames = [i for i in tar_filenames if i != KkrimpCalculation._OUT_POTENTIAL]
- for f in tar_filenames:
- # create new tarfile without out_potential file
- fabs = os.path.join(tmpfolder_path, f)
- tf.add(fabs, arcname=os.path.basename(fabs))
- elif dry_run:
- print('dry run:')
- print('delete and retar?', delete_and_retar)
- print('tmpfolder_path', tmpfolder_path)
-
- # clean up temporary Sandbox folder
- if not dry_run:
- tmpfolder.erase()
-
-
-def clean_raw_input(successful, pks_calcs, dry_run=False):
- """
- Clean raw_input directories that contain copies of shapefun and potential files
- This however breaks provenance (strictly speaking) and therefore should only be done
- for the calculations of a successfully finished workflow (see email on mailing list from 25.11.2019).
- """
- from aiida.orm import load_node
- from aiida_kkr.calculations import KkrimpCalculation
- if successful:
- for pk in pks_calcs:
- node = load_node(pk)
- # clean only nodes that are KkrimpCalculations
- if node.process_class == KkrimpCalculation:
- raw_input_folder = node._raw_input_folder
- # clean potential and shapefun files
- for filename in [KkrimpCalculation._POTENTIAL, KkrimpCalculation._SHAPEFUN]:
- if filename in raw_input_folder.get_content_list():
- if dry_run:
- print(f'clean {filename}')
- else:
- raw_input_folder.remove_path(filename)
- elif dry_run:
- print('no raw_inputs to clean')
-
-
-def clean_sfd(sfd_to_clean, nkeep=30):
- """
- Clean up potential file (keep only header) to save space in the repository
- WARNING: this breaks cachability!
- """
- with sfd_to_clean.open(sfd_to_clean.filename) as f:
- txt = f.readlines()
- # remove all lines after nkeep lines
- txt2 = txt[:nkeep]
- # add note to end of file
- txt2 += [u'WARNING: REST OF FILE WAS CLEANED SO SAVE SPACE!!!\n']
- # overwrite file
- with sfd_to_clean.open(sfd_to_clean.filename, 'w') as fnew:
- fnew.writelines(txt2)
-
-
@calcfunction
def extract_imp_pot_sfd(retrieved_folder):
"""
From 94ee901bc55c6ac6c60c33fc5788b6450d82c3c0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Philipp=20R=C3=BC=C3=9Fmann?=
Date: Tue, 31 Oct 2023 12:43:56 +0000
Subject: [PATCH 4/5] Fix pylint
---
aiida_kkr/parsers/kkrimp.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/aiida_kkr/parsers/kkrimp.py b/aiida_kkr/parsers/kkrimp.py
index 64fe4e89..93e390c6 100644
--- a/aiida_kkr/parsers/kkrimp.py
+++ b/aiida_kkr/parsers/kkrimp.py
@@ -42,7 +42,7 @@ def __init__(self, calc):
# pylint: disable=protected-access
- def parse(self, debug=False, ignore_nan=False, **kwargs):
+ def parse(self, debug=False, ignore_nan=False, **kwargs): # pylint: disable=unexpected-keyword-arg
"""
Parse output data folder, store results in database.
From 150ff9092dab98969d3a58a00e41d1ba963a38eb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Philipp=20R=C3=BC=C3=9Fmann?=
Date: Tue, 31 Oct 2023 14:34:30 +0000
Subject: [PATCH 5/5] Activate nan_to_num in KKRimp parser
---
aiida_kkr/parsers/kkrimp.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/aiida_kkr/parsers/kkrimp.py b/aiida_kkr/parsers/kkrimp.py
index 93e390c6..146d8fb5 100644
--- a/aiida_kkr/parsers/kkrimp.py
+++ b/aiida_kkr/parsers/kkrimp.py
@@ -42,7 +42,7 @@ def __init__(self, calc):
# pylint: disable=protected-access
- def parse(self, debug=False, ignore_nan=False, **kwargs): # pylint: disable=unexpected-keyword-arg
+ def parse(self, debug=False, ignore_nan=True, **kwargs): # pylint: disable=unexpected-keyword-arg
"""
Parse output data folder, store results in database.