From 84d6e5e9dfd81de674135f5a97d89b870ffed166 Mon Sep 17 00:00:00 2001 From: bastonero Date: Thu, 23 Nov 2023 20:06:11 +0000 Subject: [PATCH 1/3] `PhBaseWorkChain`: better handler for convergence Plain lowering down the alpha mix could not work always. The `nmix_ph` is already an improvement, leading to the usage of more iterations into the mixing. The rate of the alpha mix change is also increased, and below a certain threshold a multi mix approach is tried. Afterwards, the handler finishes the strategies. --- .../workflows/ph/base.py | 37 ++++++++++++++++--- tests/workflows/ph/test_base.py | 24 ++++++++++-- 2 files changed, 53 insertions(+), 8 deletions(-) diff --git a/src/aiida_quantumespresso/workflows/ph/base.py b/src/aiida_quantumespresso/workflows/ph/base.py index e673ccb52..671cbb2ff 100644 --- a/src/aiida_quantumespresso/workflows/ph/base.py +++ b/src/aiida_quantumespresso/workflows/ph/base.py @@ -22,8 +22,9 @@ class PhBaseWorkChain(ProtocolMixin, BaseRestartWorkChain): defaults = AttributeDict({ 'delta_factor_max_seconds': 0.95, - 'delta_factor_alpha_mix': 0.90, - 'alpha_mix': 0.70, + 'delta_factor_alpha_mix': 0.65, + 'nmix_ph': 4, + 'alpha_mix': 0.7, }) @classmethod @@ -257,13 +258,39 @@ def handle_out_of_walltime(self, node): @process_handler(priority=410, exit_codes=PhCalculation.exit_codes.ERROR_CONVERGENCE_NOT_REACHED) def handle_convergence_not_reached(self, node): """Handle `ERROR_CONVERGENCE_NOT_REACHED` exit code: decrease the mixing beta and restart.""" + self.ctx.restart_calc = node factor = self.defaults.delta_factor_alpha_mix + + nmix_ph = self.ctx.inputs.parameters.get('INPUTPH', {}).get('nmix_ph', self.defaults.nmix_ph) + + if nmix_ph < 20: # in all these cases, better trying to use more iterations in the mixing first + if nmix_ph < 8: # 8~20 is the recommended range on the Quantum ESPRESSO documentation + nmix_ph_new = 8 + if nmix_ph >= 8: + nmix_ph_new = 20 + + self.ctx.inputs.parameters.setdefault('INPUTPH', {})['nmix_ph'] = nmix_ph_new + + action = f'increased number of mixing iteration from {nmix_ph} to {nmix_ph_new} and restarting' + self.report_error_handled(node, action) + + return ProcessHandlerReport(True) + + # now try playing with the mixing parameters alpha_mix = self.ctx.inputs.parameters.get('INPUTPH', {}).get('alpha_mix(1)', self.defaults.alpha_mix) alpha_mix_new = alpha_mix * factor - self.ctx.restart_calc = node - self.ctx.inputs.parameters.setdefault('INPUTPH', {})['alpha_mix(1)'] = alpha_mix_new + if self.ctx.inputs.parameters.get('INPUTPH', {}).get('alpha_mix(20)', -1) != -1: + action = 'no more efficient strategies for convergence.' + self.report_error_handled(node, action) + return ProcessHandlerReport(False) + + if alpha_mix_new >= 0.1: + self.ctx.inputs.parameters.setdefault('INPUTPH', {})['alpha_mix(1)'] = alpha_mix_new + action = f'reduced alpha_mix from {alpha_mix} to {alpha_mix_new} and restarting' + else: + self.ctx.inputs.parameters.setdefault('INPUTPH', {})['alpha_mix(20)'] = 0.4 + action = f'introduing alpha_mix(20)={alpha_mix_new} and restarting' - action = f'reduced alpha_mix from {alpha_mix} to {alpha_mix_new} and restarting' self.report_error_handled(node, action) return ProcessHandlerReport(True) diff --git a/tests/workflows/ph/test_base.py b/tests/workflows/ph/test_base.py index aaa6b5467..80ad2a5e8 100644 --- a/tests/workflows/ph/test_base.py +++ b/tests/workflows/ph/test_base.py @@ -99,15 +99,33 @@ def test_handle_convergence_not_reached(generate_workchain_ph): process.setup() process.validate_parameters() + result = process.handle_convergence_not_reached(process.ctx.children[-1]) + assert isinstance(result, ProcessHandlerReport) + assert result.do_break + assert process.ctx.inputs.parameters['INPUTPH']['nmix_ph'] == 8 + + result = process.handle_convergence_not_reached(process.ctx.children[-1]) + assert isinstance(result, ProcessHandlerReport) + assert result.do_break + assert process.ctx.inputs.parameters['INPUTPH']['nmix_ph'] == 20 + alpha_new = PhBaseWorkChain.defaults.alpha_mix * PhBaseWorkChain.defaults.delta_factor_alpha_mix + for _ in range(4): + result = process.handle_convergence_not_reached(process.ctx.children[-1]) + assert isinstance(result, ProcessHandlerReport) + assert result.do_break + assert process.ctx.inputs.parameters['INPUTPH']['alpha_mix(1)'] == alpha_new + alpha_new = alpha_new * PhBaseWorkChain.defaults.delta_factor_alpha_mix + result = process.handle_convergence_not_reached(process.ctx.children[-1]) assert isinstance(result, ProcessHandlerReport) assert result.do_break - assert process.ctx.inputs.parameters['INPUTPH']['alpha_mix(1)'] == alpha_new + assert process.ctx.inputs.parameters['INPUTPH']['alpha_mix(20)'] == 0.4 - result = process.inspect_process() - assert result.status == 0 + result = process.handle_convergence_not_reached(process.ctx.children[-1]) + assert isinstance(result, ProcessHandlerReport) + assert not result.do_break def test_handle_diagonalization_errors(generate_workchain_ph): From b59356582449636920ade99f01a6c1287209a28a Mon Sep 17 00:00:00 2001 From: bastonero Date: Mon, 27 Nov 2023 09:36:58 +0000 Subject: [PATCH 2/3] Improve logic --- src/aiida_quantumespresso/workflows/ph/base.py | 16 +++++----------- tests/workflows/ph/test_base.py | 7 +------ 2 files changed, 6 insertions(+), 17 deletions(-) diff --git a/src/aiida_quantumespresso/workflows/ph/base.py b/src/aiida_quantumespresso/workflows/ph/base.py index 671cbb2ff..d9e06f26f 100644 --- a/src/aiida_quantumespresso/workflows/ph/base.py +++ b/src/aiida_quantumespresso/workflows/ph/base.py @@ -22,9 +22,9 @@ class PhBaseWorkChain(ProtocolMixin, BaseRestartWorkChain): defaults = AttributeDict({ 'delta_factor_max_seconds': 0.95, - 'delta_factor_alpha_mix': 0.65, + 'delta_factor_alpha_mix': 0.5, 'nmix_ph': 4, - 'alpha_mix': 0.7, + 'alpha_mix': 0.4, }) @classmethod @@ -263,15 +263,9 @@ def handle_convergence_not_reached(self, node): nmix_ph = self.ctx.inputs.parameters.get('INPUTPH', {}).get('nmix_ph', self.defaults.nmix_ph) - if nmix_ph < 20: # in all these cases, better trying to use more iterations in the mixing first - if nmix_ph < 8: # 8~20 is the recommended range on the Quantum ESPRESSO documentation - nmix_ph_new = 8 - if nmix_ph >= 8: - nmix_ph_new = 20 - - self.ctx.inputs.parameters.setdefault('INPUTPH', {})['nmix_ph'] = nmix_ph_new - - action = f'increased number of mixing iteration from {nmix_ph} to {nmix_ph_new} and restarting' + if nmix_ph < 8: # 8~20 is the recommended range on the Quantum ESPRESSO documentation + self.ctx.inputs.parameters.setdefault('INPUTPH', {})['nmix_ph'] = 8 + action = f'increased number of mixing iteration from {nmix_ph} to 8 and restarting' self.report_error_handled(node, action) return ProcessHandlerReport(True) diff --git a/tests/workflows/ph/test_base.py b/tests/workflows/ph/test_base.py index 80ad2a5e8..edef058a1 100644 --- a/tests/workflows/ph/test_base.py +++ b/tests/workflows/ph/test_base.py @@ -104,14 +104,9 @@ def test_handle_convergence_not_reached(generate_workchain_ph): assert result.do_break assert process.ctx.inputs.parameters['INPUTPH']['nmix_ph'] == 8 - result = process.handle_convergence_not_reached(process.ctx.children[-1]) - assert isinstance(result, ProcessHandlerReport) - assert result.do_break - assert process.ctx.inputs.parameters['INPUTPH']['nmix_ph'] == 20 - alpha_new = PhBaseWorkChain.defaults.alpha_mix * PhBaseWorkChain.defaults.delta_factor_alpha_mix - for _ in range(4): + for _ in range(2): # this is dependent on PhBaseWorkChain.defaults.delta_factor_alpha_mix result = process.handle_convergence_not_reached(process.ctx.children[-1]) assert isinstance(result, ProcessHandlerReport) assert result.do_break From c554577c3a45c96fd7713ffd9302f665c83769b1 Mon Sep 17 00:00:00 2001 From: bastonero Date: Tue, 28 Nov 2023 12:32:24 +0000 Subject: [PATCH 3/3] Improve `ph` protocols Add `alpha_mix` and `ndim_ph`. --- src/aiida_quantumespresso/workflows/ph/base.py | 2 +- src/aiida_quantumespresso/workflows/protocols/ph/base.yaml | 2 ++ tests/workflows/protocols/ph/test_base/test_default.yml | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/aiida_quantumespresso/workflows/ph/base.py b/src/aiida_quantumespresso/workflows/ph/base.py index bfb78e353..ab3001aab 100644 --- a/src/aiida_quantumespresso/workflows/ph/base.py +++ b/src/aiida_quantumespresso/workflows/ph/base.py @@ -25,7 +25,7 @@ class PhBaseWorkChain(ProtocolMixin, BaseRestartWorkChain): 'delta_factor_max_seconds': 0.95, 'delta_factor_alpha_mix': 0.5, 'nmix_ph': 4, - 'alpha_mix': 0.4, + 'alpha_mix': 0.7, }) @classmethod diff --git a/src/aiida_quantumespresso/workflows/protocols/ph/base.yaml b/src/aiida_quantumespresso/workflows/protocols/ph/base.yaml index 126c6b836..b281d8a90 100644 --- a/src/aiida_quantumespresso/workflows/protocols/ph/base.yaml +++ b/src/aiida_quantumespresso/workflows/protocols/ph/base.yaml @@ -10,6 +10,8 @@ default_inputs: withmpi: True parameters: INPUTPH: + alpha_mix: 0.4 + nmix_ph: 8 tr2_ph: 1.0e-18 qpoints: - 3 diff --git a/tests/workflows/protocols/ph/test_base/test_default.yml b/tests/workflows/protocols/ph/test_base/test_default.yml index 845fe3211..530f5282f 100644 --- a/tests/workflows/protocols/ph/test_base/test_default.yml +++ b/tests/workflows/protocols/ph/test_base/test_default.yml @@ -10,6 +10,8 @@ ph: withmpi: true parameters: INPUTPH: + alpha_mix: 0.4 + nmix_ph: 8 tr2_ph: 1.0e-18 qpoints: - - 3