Skip to content

Commit

Permalink
Improvements to stability
Browse files Browse the repository at this point in the history
- decrease default mixing factor in kkrimp workflow
- allow to use unconverged inputs to combine_imps workflow
- allow integer and boolean values in fix_dir entry of nonco_angle input to Kkr(imp)Calculations
  • Loading branch information
PhilippRue committed Oct 2, 2024
1 parent 327140c commit 40d8fa4
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 34 deletions.
5 changes: 4 additions & 1 deletion aiida_kkr/calculations/kkr.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
'IAS-1/PGI-1, Germany. All rights reserved.')
__license__ = 'MIT license, see LICENSE.txt file'

__version__ = '0.13.0'
__version__ = '0.13.1'

__contributors__ = ('Jens Bröder', 'Philipp Rüßmann')

Expand Down Expand Up @@ -1062,6 +1062,9 @@ def _use_initial_noco_angles(self, parameters, structure, tempfolder):
raise InputValidationError(
f'Error: theta value out of range (0..180): iatom={iatom}, theta={theta}'
)
# convert fix_dir to boolean if given as integer
if not isinstance(fix_dir, bool):
fix_dir = (fix_dir == 1)
# write line
noco_angle_file.write(f' {theta} {phi} {fix_dir[iatom]}\n')

Expand Down
5 changes: 4 additions & 1 deletion aiida_kkr/calculations/kkrimp.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,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.10.1'
__version__ = '0.10.2'
__contributors__ = (u'Philipp Rüßmann', u'Fabian Bertoldo')

#TODO: implement 'ilayer_center' consistency check
Expand Down Expand Up @@ -910,6 +910,9 @@ def _write_kkrflex_angle(self, parameters, GFhost_folder, tempfolder):
)
if phi < 0 or phi > 360:
raise InputValidationError(f'Error: phi value out of range (0..360): iatom={iatom}, phi={phi}')
# convert fix_dir to integer if given as boolean
if isinstance(fix_dir, bool):
fix_dir = (1 if fix_dir else 0)
# write line
kkrflex_angle_file.write(f' {theta} {phi} {fix_dir}\n')

Expand Down
69 changes: 42 additions & 27 deletions aiida_kkr/workflows/_combine_imps.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
__copyright__ = (u'Copyright (c), 2020, Forschungszentrum Jülich GmbH, '
'IAS-1/PGI-1, Germany. All rights reserved.')
__license__ = 'MIT license, see LICENSE.txt file'
__version__ = '0.3.4'
__version__ = '0.3.5'
__contributors__ = (u'Philipp Rüßmann , Rubel Mozumder, David Antognini Silva')

# activate debug writeout
Expand Down Expand Up @@ -78,6 +78,7 @@ class combine_imps_wc(WorkChain):
_workflowversion = __version__
_wf_default = {
'jij_run': False, # Any kind of addition in _wf_default should be updated into the start() as well.
'allow_unconverged_inputs': False, # start calculation only if previous impurity calculations are converged?
}

@classmethod
Expand Down Expand Up @@ -230,12 +231,19 @@ def start(self): # pylint: disable=inconsistent-return-statements
"""
message = f'INFO: started combine_imps_wc workflow version {self._workflowversion}'
self.report(message)
if 'wf_parameters_overwrite' in self.inputs:
self.ctx.wf_parameters_overwrite = self.inputs.wf_parameters_overwrite

self.ctx.run_options = {'jij_run': False}
self.ctx.imp1 = self.get_imp_node_from_input(iimp=1)
self.ctx.imp2 = self.get_imp_node_from_input(iimp=2)
self.ctx.run_options = self._wf_default
self.ctx.allow_unconverged_inputs = self._wf_default.get('allow_unconverged_inputs', False)
if 'wf_parameters_overwrite' in self.inputs:
self.ctx.wf_parameters_overwrite = self.inputs.wf_parameters_overwrite.get_dict()
self.ctx.allow_unconverged_inputs = self.ctx.wf_parameters_overwrite.get('global', {}).get('allow_unconverged_inputs', False)

exit_code, self.ctx.imp1 = self.get_imp_node_from_input(iimp=1)
if exit_code != 0:
return exit_code
exit_code, self.ctx.imp2 = self.get_imp_node_from_input(iimp=2)
if exit_code != 0:
return exit_code
self.ctx.single_vs_single = True # It is assumed

# find and compare host structures for the two imps to make sure the impurities are consistent
Expand Down Expand Up @@ -278,7 +286,7 @@ def combine_single_single(self):
imp_1 = self.ctx.imp1
imp_2 = self.ctx.imp2
# check for the impurity1 whether from single kkr_imp_wc or not
if imp_1.process_class == KkrCalculation or imp_1.process_class == KkrimpCalculation:
if imp_1.process_class == KkrimpCalculation:
Zimp_num_1 = imp_1.inputs.impurity_info.get_dict().get('Zimp')
if isinstance(Zimp_num_1, list):
if len(Zimp_num_1) > 1:
Expand All @@ -293,7 +301,7 @@ def combine_single_single(self):
single_imp_1 = False

# check for the impurity2 whether from single kkr_imp_wc or not
if imp_2.process_class == KkrCalculation or imp_2.process_class == KkrimpCalculation:
if imp_2.process_class == KkrimpCalculation:
Zimp_num_2 = imp_2.inputs.impurity_info.get_dict().get('Zimp')
if isinstance(Zimp_num_2, list):
if len(Zimp_num_2) > 1:
Expand Down Expand Up @@ -335,17 +343,14 @@ def extract_imps_info_exact_cluster(self):
self.report(
f'DEBUG: The is the imps_info_in_exact_cluster dict for single-single imp calc: {imps_info_in_exact_cluster}\n'
)
return imps_info_in_exact_cluster
return 0, imps_info_in_exact_cluster
else:
imp1_input = self.ctx.imp1
# This 'if clause' to extract the imps_info_in_exact_cluster from workflow_info of the input impurity node
if imp1_input.process_class == combine_imps_wc:
parent_combine_wc = imp1_input
out_workflow_info = parent_combine_wc.outputs.workflow_info


# out_workflow_info = parent_combine_wc.get_outgoing(link_label_filter='workflow_info').all()[0].node

elif imp1_input.process_class == KkrimpCalculation:
kkrimp_sub = imp1_input.get_incoming(node_class=kkr_imp_sub_wc).all()[0].node
parent_combine_wc = kkrimp_sub.get_incoming(node_class=combine_imps_wc).all()[0].node
Expand All @@ -364,8 +369,12 @@ def extract_imps_info_exact_cluster(self):
parent_input_imp2 = parent_combine_wc.inputs.impurity2_output_node
parent_input_offset = parent_combine_wc.inputs.offset_imp2

parent_imp1_wc_or_calc = self.get_imp_node_from_input(impurity_output_node=parent_input_imp1)
parent_imp2_wc_or_calc = self.get_imp_node_from_input(impurity_output_node=parent_input_imp2)
exit_code, parent_imp1_wc_or_calc = self.get_imp_node_from_input(impurity_output_node=parent_input_imp1)
if exit_code != 0:
return exit_code, None
exit_code, parent_imp2_wc_or_calc = self.get_imp_node_from_input(impurity_output_node=parent_input_imp2)
if exit_code != 0:
return exit_code, None

# Here below imps_info_in_exact_cluster is construct from the inputs impurity1_output_node, and impurity2_output_node as the idea was not calculated in the old version attempt of the combine_imps_wc.

Expand All @@ -384,7 +393,7 @@ def extract_imps_info_exact_cluster(self):
imps_info_in_exact_cluster['ilayers'].append(imp2_impurity_info.get_dict()['ilayer_center'])
# TODO: Delete the below print line as it is for deburging
self.report(f'DEBUG: The is the imps_info_in_exact_cluster dict: {imps_info_in_exact_cluster}\n')
return imps_info_in_exact_cluster
return 0, imps_info_in_exact_cluster # return also exit code

def get_impinfo_from_hostGF(self, imp_calc):
"""
Expand Down Expand Up @@ -454,28 +463,26 @@ def get_imp_node_from_input(self, impurity_output_node=None, iimp=1):
inc = imp_out.get_incoming(link_label_filter='workflow_info').all()
if len(inc) != 1:
self.report(f'input node of imp {iimp} inconsistent')
return self.exit_codes.ERROR_INPUT_NODE_INCONSISTENT # pylint: disable=maybe-no-member
return self.exit_codes.ERROR_INPUT_NODE_INCONSISTENT, None # pylint: disable=maybe-no-member
imp = inc[0].node

# consistency checks of input nodes
# check if input calc was converged etc.
if not self._check_input_imp(imp):
self.report(f'something wrong with imp {iimp}: {imp}')
return self.exit_codes.ERROR_SOMETHING_WENT_WRONG # pylint: disable=maybe-no-member
return self.exit_codes.ERROR_SOMETHING_WENT_WRONG, None # pylint: disable=maybe-no-member

return imp
# return exit code and imp calculation
return 0, imp

def _check_input_imp(self, imp_calc_or_wf):
"""
check if input calculation is a kkr_imp_wc workflow which did converge
check if input calculation is of the right process_class and if it did converge
"""

if imp_calc_or_wf.process_class == KkrimpCalculation:
# imp_calc_or_wf can be KkrimpClaculation
if not imp_calc_or_wf.outputs.output_parameters['convergence_group']['calculation_converged']:
return False
else:
# imp_calc_or_wf should be kkr_imp_wc or kkr_imp_sub_wc or combine_imps_wc workflow
if imp_calc_or_wf.process_class != KkrimpCalculation:
# if imp_calc_or_wf is not a KkrimpCalculation
# check if imp_calc_or_wf is kkr_imp_wc, kkr_imp_sub_wc or combine_imps_wc workflow
if not isinstance(imp_calc_or_wf, WorkChainNode):
self.report(f'impurity_workflow not a WorkChainNode: {imp_calc_or_wf}')
return False
Expand All @@ -487,7 +494,12 @@ def _check_input_imp(self, imp_calc_or_wf):
self.report(f'impurity_workflow class is wrong: {imp_calc_or_wf}')
return False

if (not self.ctx.allow_unconverged_inputs):
# calculation should be converged
if imp_calc_or_wf.process_class == KkrimpCalculation:
if not imp_calc_or_wf.outputs.output_parameters['convergence_group']['calculation_converged']:
self.report(f'impurity calculation not converged: {imp_calc_or_wf}')
return False
if imp_calc_or_wf.process_class == kkr_imp_wc:
if not imp_calc_or_wf.outputs.workflow_info.get_dict().get('converged'):
self.report('impurity_workflow not converged')
Expand Down Expand Up @@ -532,7 +544,10 @@ def create_big_cluster(self): # pylint: disable=inconsistent-return-statements
self.report(f'imp info 1: {impinfo1}')
self.report(f'imp info 2: {impinfo2}')

self.ctx.imps_info_in_exact_cluster = self.extract_imps_info_exact_cluster()
exit_code, self.ctx.imps_info_in_exact_cluster = self.extract_imps_info_exact_cluster()
if exit_code != 0:
return exit_code

imps_info_in_exact_cluster = self.ctx.imps_info_in_exact_cluster
if single_single:
if offset_imp2.get_dict()['index'] < 0:
Expand Down Expand Up @@ -706,7 +721,7 @@ def update_params(self):
run_options = self.ctx.run_options
# Update the scf_wf_parameters from the wf_parameters_overwrite
if 'wf_parameters_overwrite' in self.inputs:
wf_parameters_overwrite = self.ctx.wf_parameters_overwrite.get_dict()
wf_parameters_overwrite = self.ctx.wf_parameters_overwrite

for key, val in wf_parameters_overwrite.items():
# Update the scf_wf_parameters from wf_parameters_overwrite
Expand Down
10 changes: 5 additions & 5 deletions aiida_kkr/workflows/kkr_imp_sub.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.10.3'
__version__ = '0.10.4'
__contributors__ = (u'Fabian Bertoldo', u'Philipp Ruessmann', u'David Antognini Silva')

#TODO: work on return results function
Expand Down Expand Up @@ -66,13 +66,13 @@ class kkr_imp_sub_wc(WorkChain):

_wf_default = {
'kkr_runmax': 5, # Maximum number of kkr jobs/starts (defauld iterations per start)
'convergence_criterion': 1 * 10**-7, # Stop if charge denisty is converged below this value
'convergence_criterion': 1e-7, # Stop if charge denisty is converged below this value
'mixreduce': 0.5, # reduce mixing factor by this factor if calculaito fails due to too large mixing
'threshold_aggressive_mixing': 1 * 10**-2, # threshold after which agressive mixing is used
'strmix': 0.03, # mixing factor of simple mixing
'threshold_aggressive_mixing': 1e-2, # threshold after which agressive mixing is used
'strmix': 0.01, # mixing factor of simple mixing
'nsteps': 50, # number of iterations done per KKR calculation
'aggressive_mix': 5, # type of aggressive mixing (3: broyden's 1st, 4: broyden's 2nd, 5: generalized anderson)
'aggrmix': 0.05, # mixing factor of aggressive mixing
'aggrmix': 0.01, # mixing factor of aggressive mixing
'broyden-number': 20, # number of potentials to 'remember' for Broyden's mixing
'nsimplemixfirst': 0, # number of simple mixing step at the beginning of Broyden mixing
'mag_init': False, # initialize and converge magnetic calculation
Expand Down

0 comments on commit 40d8fa4

Please sign in to comment.