From 8f1066ae960a9dd4d2766b06bcdd7eca2f795981 Mon Sep 17 00:00:00 2001 From: Marnik Bercx Date: Fri, 24 Nov 2023 13:51:24 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=91=8C=20`PwBaseWorkChain`:=20Improve=20h?= =?UTF-8?q?andling=20of=20SCF=20convergence=20issues?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The current error handler for the `PwBaseWorkChain` that deals with SCF convergence issues only tries to reduce the `mixing-beta` by 20% each time the calculation fails, and doesn't consider the rate of convergence. Here we improve the error handling for this case by calculating the slope on the logarithm of the "scf accuracy". Based on some statistics presented in https://github.com/aiidateam/aiida-quantumespresso/issues/961 We noted two points: 1. Most of the calculations that converge do so within 50 SCF steps. 2. For those that don't, there is a very low chance of convergence in case the scf accuracy slope is higher than -0.1. Hence, we: * Limit the default number of maximum steps (`electron_maxstep`) to 50. * In case of SCF convergence failure, check the scf accuracy slope. If < -0.1, do a full restart. * Else, check the `mixing_beta`. If above 0.1, half it and restart the calculation. --- .../workflows/protocols/pw/base.yaml | 2 +- .../workflows/pw/base.py | 37 +++++++++++++++---- .../protocols/pw/test_bands/test_default.yml | 6 +-- .../protocols/pw/test_base/test_default.yml | 2 +- .../protocols/pw/test_relax/test_default.yml | 4 +- .../protocols/test_pdos/test_default.yml | 4 +- .../xspectra/test_core/test_default.yml | 2 +- .../xspectra/test_crystal/test_default.yml | 4 +- 8 files changed, 41 insertions(+), 20 deletions(-) diff --git a/src/aiida_quantumespresso/workflows/protocols/pw/base.yaml b/src/aiida_quantumespresso/workflows/protocols/pw/base.yaml index 200edd9da..4ec391f0f 100644 --- a/src/aiida_quantumespresso/workflows/protocols/pw/base.yaml +++ b/src/aiida_quantumespresso/workflows/protocols/pw/base.yaml @@ -25,7 +25,7 @@ default_inputs: smearing: cold degauss: 0.01 ELECTRONS: - electron_maxstep: 80 + electron_maxstep: 50 mixing_beta: 0.4 default_protocol: moderate protocols: diff --git a/src/aiida_quantumespresso/workflows/pw/base.py b/src/aiida_quantumespresso/workflows/pw/base.py index 4c31dc292..8f9ee17b2 100644 --- a/src/aiida_quantumespresso/workflows/pw/base.py +++ b/src/aiida_quantumespresso/workflows/pw/base.py @@ -29,10 +29,11 @@ class PwBaseWorkChain(ProtocolMixin, BaseRestartWorkChain): 'qe': qe_defaults, 'delta_threshold_degauss': 30, 'delta_factor_degauss': 0.1, - 'delta_factor_mixing_beta': 0.8, + 'delta_factor_mixing_beta': 0.5, 'delta_factor_max_seconds': 0.95, 'delta_factor_nbnd': 0.05, 'delta_minimum_nbnd': 4, + 'conv_slope_threshold': -0.1, }) @classmethod @@ -563,16 +564,36 @@ def handle_electronic_convergence_not_reached(self, calculation): Decrease the mixing beta and fully restart from the previous calculation. """ - factor = self.defaults.delta_factor_mixing_beta + import numpy + + scf_accuracy = calculation.tools.get_scf_accuracy(0) + scf_accuracy_slope = numpy.polyfit(numpy.arange(0, len(scf_accuracy)), numpy.log(scf_accuracy), 1)[0] + + if scf_accuracy_slope < self.defaults.conv_slope_threshold: + + action = ( + 'electronic convergence not reached but the scf accuracy is decreasing: restart from the last ' + 'calculation.' + ) + self.set_restart_type(RestartType.FULL, calculation.outputs.remote_folder) + self.report_error_handled(calculation, action) + return ProcessHandlerReport(True) + mixing_beta = self.ctx.inputs.parameters.get('ELECTRONS', {}).get('mixing_beta', self.defaults.qe.mixing_beta) - mixing_beta_new = mixing_beta * factor - self.ctx.inputs.parameters['ELECTRONS']['mixing_beta'] = mixing_beta_new - action = f'reduced beta mixing from {mixing_beta} to {mixing_beta_new} and restarting from the last calculation' + if mixing_beta > 0.1: - self.set_restart_type(RestartType.FULL, calculation.outputs.remote_folder) - self.report_error_handled(calculation, action) - return ProcessHandlerReport(True) + mixing_beta_new = mixing_beta * self.defaults.delta_factor_mixing_beta + + self.ctx.inputs.parameters['ELECTRONS']['mixing_beta'] = mixing_beta_new + action = ( + f'reduced beta mixing from {mixing_beta} to {mixing_beta_new} and restarting from the last ' + 'calculation' + ) + + self.set_restart_type(RestartType.FULL, calculation.outputs.remote_folder) + self.report_error_handled(calculation, action) + return ProcessHandlerReport(True) @process_handler(priority=420, exit_codes=[ PwCalculation.exit_codes.WARNING_ELECTRONIC_CONVERGENCE_NOT_REACHED, diff --git a/tests/workflows/protocols/pw/test_bands/test_default.yml b/tests/workflows/protocols/pw/test_bands/test_default.yml index f3ab01bde..3659ae310 100644 --- a/tests/workflows/protocols/pw/test_bands/test_default.yml +++ b/tests/workflows/protocols/pw/test_bands/test_default.yml @@ -20,7 +20,7 @@ bands: conv_thr: 4.0e-10 diago_full_acc: true diagonalization: paro - electron_maxstep: 80 + electron_maxstep: 50 mixing_beta: 0.4 startingpot: file SYSTEM: @@ -60,7 +60,7 @@ relax: tstress: true ELECTRONS: conv_thr: 4.0e-10 - electron_maxstep: 80 + electron_maxstep: 50 mixing_beta: 0.4 SYSTEM: degauss: 0.01 @@ -95,7 +95,7 @@ scf: tstress: true ELECTRONS: conv_thr: 4.0e-10 - electron_maxstep: 80 + electron_maxstep: 50 mixing_beta: 0.4 SYSTEM: degauss: 0.01 diff --git a/tests/workflows/protocols/pw/test_base/test_default.yml b/tests/workflows/protocols/pw/test_base/test_default.yml index 3e08ba059..052b37987 100644 --- a/tests/workflows/protocols/pw/test_base/test_default.yml +++ b/tests/workflows/protocols/pw/test_base/test_default.yml @@ -18,7 +18,7 @@ pw: tstress: true ELECTRONS: conv_thr: 4.0e-10 - electron_maxstep: 80 + electron_maxstep: 50 mixing_beta: 0.4 SYSTEM: degauss: 0.01 diff --git a/tests/workflows/protocols/pw/test_relax/test_default.yml b/tests/workflows/protocols/pw/test_relax/test_default.yml index 10ad26638..c88c52844 100644 --- a/tests/workflows/protocols/pw/test_relax/test_default.yml +++ b/tests/workflows/protocols/pw/test_relax/test_default.yml @@ -22,7 +22,7 @@ base: tstress: true ELECTRONS: conv_thr: 4.0e-10 - electron_maxstep: 80 + electron_maxstep: 50 mixing_beta: 0.4 SYSTEM: degauss: 0.01 @@ -54,7 +54,7 @@ base_final_scf: tstress: true ELECTRONS: conv_thr: 4.0e-10 - electron_maxstep: 80 + electron_maxstep: 50 mixing_beta: 0.4 SYSTEM: degauss: 0.01 diff --git a/tests/workflows/protocols/test_pdos/test_default.yml b/tests/workflows/protocols/test_pdos/test_default.yml index ac1c27ad6..241890693 100644 --- a/tests/workflows/protocols/test_pdos/test_default.yml +++ b/tests/workflows/protocols/test_pdos/test_default.yml @@ -32,7 +32,7 @@ nscf: tstress: true ELECTRONS: conv_thr: 4.0e-10 - electron_maxstep: 80 + electron_maxstep: 50 mixing_beta: 0.4 SYSTEM: ecutrho: 240.0 @@ -74,7 +74,7 @@ scf: tstress: true ELECTRONS: conv_thr: 4.0e-10 - electron_maxstep: 80 + electron_maxstep: 50 mixing_beta: 0.4 SYSTEM: degauss: 0.01 diff --git a/tests/workflows/protocols/xspectra/test_core/test_default.yml b/tests/workflows/protocols/xspectra/test_core/test_default.yml index 982fac60f..b4b9321fd 100644 --- a/tests/workflows/protocols/xspectra/test_core/test_default.yml +++ b/tests/workflows/protocols/xspectra/test_core/test_default.yml @@ -37,7 +37,7 @@ scf: tstress: true ELECTRONS: conv_thr: 4.0e-10 - electron_maxstep: 80 + electron_maxstep: 50 mixing_beta: 0.4 SYSTEM: degauss: 0.01 diff --git a/tests/workflows/protocols/xspectra/test_crystal/test_default.yml b/tests/workflows/protocols/xspectra/test_crystal/test_default.yml index ee0c5bc9b..e3c7803e7 100644 --- a/tests/workflows/protocols/xspectra/test_crystal/test_default.yml +++ b/tests/workflows/protocols/xspectra/test_crystal/test_default.yml @@ -25,7 +25,7 @@ core: tstress: true ELECTRONS: conv_thr: 4.0e-10 - electron_maxstep: 80 + electron_maxstep: 50 mixing_beta: 0.4 SYSTEM: degauss: 0.01 @@ -100,7 +100,7 @@ relax: tstress: true ELECTRONS: conv_thr: 4.0e-10 - electron_maxstep: 80 + electron_maxstep: 50 mixing_beta: 0.4 SYSTEM: degauss: 0.01