def _handle_error_read_namelists(self, calculation): """ The calculation failed because it could not read the generated input file """ if any(['read_namelists' in w for w in calculation.res.warnings]): self.abort_nowait('PwCalculation<{}> failed because of an invalid input file'.format(calculation.pk)) return ErrorHandlerReport(True, True)
def _handle_fatal_error_read_namelists(self, calculation): """ The calculation failed because it could not read the generated input file """ if any(['reading inputph namelist' in w for w in calculation.res.warnings]): self.report('PhCalculation<{}> failed because of an invalid input file'.format(calculation.pk)) return ErrorHandlerReport(True, True, self.exit_codes.ERROR_CALCULATION_INVALID_INPUT_FILE)
def _handle_error_convergence_not_reached(self, calculation): """ At the end of the scf cycle, the convergence threshold was not reached. We simply restart from the previous calculation without changing any of the input parameters """ if 'The scf cycle did not reach convergence.' in calculation.res.warnings: self.ctx.restart_calc = calculation self.report('PwCalculation<{}> did not converge, restart from previous calculation'.format(calculation.pk)) return ErrorHandlerReport(True, True)
def _handle_error_exceeded_maximum_walltime(self, calculation): """ Calculation ended nominally but ran out of allotted wall time """ if 'Maximum CPU time exceeded' in calculation.res.warnings: self.ctx.restart_calc = calculation self.report('PwCalculation<{}> terminated because maximum wall time was exceeded, restarting' .format(calculation.pk)) return ErrorHandlerReport(True, True)
def _handle_error_missing_perturbation_file(self, calculation): """ The calculation was run in `collect_chi` mode, however, the code did not find all the perturbation files that it expected based on the number of Hubbard kinds in the parent calculation """ if calculation.finish_status == HpParser.ERROR_MISSING_PERTURBATION_FILE: self.report( 'one or more perturbation files that were expected for the collect_chi calculation, are missing' ) return ErrorHandlerReport(True, True, self.ERROR_MISSING_PERTURBATION_FILE)
def _handle_insufficient_bands(self, calculation): """Calculation successfully converged but included to few bands, so increase them and restart from scratch.""" nbnd_cur = calculation.outputs.output_parameters.get_dict()['number_of_bands'] nbnd_new = nbnd_cur + max(int(nbnd_cur * self.defaults.delta_factor_nbnd), self.defaults.delta_minimum_nbnd) self.ctx.inputs.parameters.setdefault('SYSTEM', {})['nbnd'] = nbnd_new self.ctx.restart_calc = None self.report('{}<{}> had insufficient bands'.format(calculation.process_label, calculation.pk)) self.report('Action taken: increased the number of bands to {} and restarting from scratch'.format(nbnd_new)) return ErrorHandlerReport(True, True)
def _handle_fatal_error_not_converged(self, calculation): """ The calculation failed because it could not read the generated input file """ if ('Phonon did not reach end of self consistency' in calculation.res.warnings): alpha_mix_old = calculation.inp.parameters.get_dict()['INPUTPH'].get('alpha_mix(1)', self.defaults.alpha_mix) alpha_mix_new = 0.9 * alpha_mix_old self.ctx.inputs.parameters['INPUTPH']['alpha_mix(1)'] = alpha_mix_new self.ctx.restart_calc = calculation self.report('PhCalculation<{}> terminated without reaching convergence, ' 'setting alpha_mix to {} and restarting'.format(calculation.pk, alpha_mix_new)) return ErrorHandlerReport(True, True)
def _handle_error_incorrect_order_atomic_positions(self, calculation): """ The structure used by the parent calculation has its kinds in the wrong order, as in that the Hubbard kinds were not added first, so they will not be printed first in the ATOMIC_POSITIONS card, which is required by the hp.x code """ if calculation.finish_status == HpParser.ERROR_INCORRECT_ORDER_ATOMIC_POSITIONS: self.report( 'the parent calculation used a structure where the Hubbard atomic positions did not appear first' ) return ErrorHandlerReport(True, True, self.ERROR_INCORRECT_ORDER_ATOMIC_POSITIONS)
def _handle_vcrelax_converged_except_final_scf(self, calculation): """Convergence reached in `vc-relax` except thresholds exceeded in final scf: consider as converged.""" exit_code_labels = [ 'ERROR_IONIC_CONVERGENCE_REACHED_EXCEPT_IN_FINAL_SCF', ] if calculation.exit_status in PwCalculation.get_exit_statuses(exit_code_labels): self.ctx.is_finished = True self.ctx.restart_calc = calculation action = 'ionic convergence thresholds met except in final scf: consider structure relaxed.' self.report_error_handled(calculation, action) self.results() # Call the results method to attach the output nodes return ErrorHandlerReport(True, True, self.exit_codes.ERROR_IONIC_CONVERGENCE_REACHED_EXCEPT_IN_FINAL_SCF)
def _handle_out_of_walltime(self, calculation): """In the case of `ERROR_OUT_OF_WALLTIME` calculation shut down neatly and we can simply restart.""" if calculation.exit_status == PwCalculation.spec().exit_codes.ERROR_OUT_OF_WALLTIME.status: try: self.ctx.inputs.structure = calculation.outputs.output_structure except exceptions.NotExistent: self.ctx.restart_calc = calculation self.report_error_handled(calculation, 'simply restart from the last calculation') else: self.ctx.restart_calc = None self.report_error_handled(calculation, 'out of walltime: structure changed so restarting from scratch') return ErrorHandlerReport(True, True)
def _handle_convergence_not_achieved(self, calculation): """In the case of `ERROR_CONVERGENCE_NOT_REACHED` decrease the mixing beta and restart from scratch.""" if calculation.exit_status == PwCalculation.exit_codes.ERROR_CONVERGENCE_NOT_REACHED.status: factor = self.defaults.delta_factor_alpha_mix 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 = calculation self.ctx.inputs.parameters.setdefault('INPUTPH', {})['alpha_mix(1)'] = alpha_mix_new action = 'reduced alpha_mix from {} to {} and restarting'.format(alpha_mix, alpha_mix_new) self.report_error_handled(calculation, action) return ErrorHandlerReport(True, True)
def _handle_electronic_convergence_not_achieved(self, calculation): """In the case of `ERROR_ELECTRONIC_CONVERGENCE_NOT_REACHED` decrease the mixing beta and restart from scratch.""" if calculation.exit_status == PwCalculation.spec().exit_codes.ERROR_ELECTRONIC_CONVERGENCE_NOT_REACHED.status: factor = self.defaults.delta_factor_mixing_beta mixing_beta = self.ctx.inputs.parameters.get('ELECTRONS', {}).get('mixing_beta', self.defaults.qe.mixing_beta) mixing_beta_new = mixing_beta * factor self.ctx.restart_calc = calculation self.ctx.inputs.parameters.setdefault('ELECTRONS', {})['mixing_beta'] = mixing_beta_new action = 'reduced beta mixing from {} to {} and restarting from the last ' \ 'calculation'.format(mixing_beta, mixing_beta_new) self.report_error_handled(calculation, action) return ErrorHandlerReport(True, True)
def _handle_error_premature_termination(self, calculation): """ Calculation did not reach the end of execution, probably because it was killed by the scheduler for running out of allotted walltime """ if 'QE ph run did not reach the end of the execution.' in calculation.res.parser_warnings: inputs = calculation.inp.parameters.get_dict() settings = self.ctx.inputs.settings factor = self.defaults.delta_factor_max_seconds max_seconds = settings.get('max_seconds', inputs['INPUTPH']['max_seconds']) max_seconds_reduced = int(max_seconds * factor) self.ctx.inputs.parameters['INPUTPH']['max_seconds'] = max_seconds_reduced self.ctx.restart_calc = calculation self.report('PwCalculation<{}> was terminated prematurely, reducing "max_seconds" from {} to {}' .format(calculation.pk, max_seconds, max_seconds_reduced)) return ErrorHandlerReport(True, True)
def _handle_relax_recoverable_ionic_convergence_error(self, calculation): """Various exit codes for recoverable `vc-relax` or `relax` calculations with failed ionic convergence. These exit codes signify that the ionic convergence thresholds were not met, but the output structure is usable, so the solution is to simply restart from scratch but from the output structure. """ exit_code_labels = [ 'ERROR_IONIC_CONVERGENCE_NOT_REACHED', 'ERROR_IONIC_CYCLE_EXCEEDED_NSTEP', 'ERROR_IONIC_CYCLE_BFGS_HISTORY_FAILURE', 'ERROR_IONIC_CYCLE_BFGS_HISTORY_AND_FINAL_SCF_FAILURE', ] if calculation.exit_status in PwCalculation.get_exit_statuses(exit_code_labels): self.ctx.restart_calc = None self.ctx.inputs.structure = calculation.outputs.output_structure action = 'no ionic convergence but clean shutdown: restarting from scratch but using output structure.' self.report_error_handled(calculation, action) return ErrorHandlerReport(True, True)
def _handle_error_diagonalization(self, calculation): """ Diagonalization failed with current scheme. Try to restart from previous clean calculation with different scheme """ input_parameters = calculation.inp.parameters.get_dict() input_electrons = input_parameters.get('ELECTRONS', {}) diagonalization = input_electrons.get('diagonalization', self.defaults['qe']['diagonalization']) if (( any(['too many bands are not converged' in w for w in calculation.res.warnings]) or any(['eigenvalues not converged' in w for w in calculation.res.warnings]) ) and ( diagonalization == 'david' )): new_diagonalization = 'cg' self.ctx.inputs.parameters['ELECTRONS']['diagonalization'] = 'cg' self.ctx.restart_calc = calculation self.report('PwCalculation<{}> failed to diagonalize with "{}" scheme'.format(diagonalization)) self.report('Restarting with diagonalization scheme "{}"'.format(new_diagonalization)) return ErrorHandlerReport(True, True)
def _handle_relax_recoverable_electronic_convergence_error(self, calculation): """Various exit codes for recoverable `vc-relax` or `relax` calculations with failed electronic convergence. These exit codes signify that the electronic convergence thresholds were not met, but the output structure is usable, so the solution is to simply restart from scratch but from the output structure. """ exit_code_labels = [ 'ERROR_IONIC_CYCLE_ELECTRONIC_CONVERGENCE_NOT_REACHED', 'ERROR_IONIC_CONVERGENCE_REACHED_FINAL_SCF_FAILED', ] if calculation.exit_status in PwCalculation.get_exit_statuses(exit_code_labels): factor = self.defaults.delta_factor_mixing_beta mixing_beta = self.ctx.inputs.parameters.get('ELECTRONS', {}).get('mixing_beta', self.defaults.qe.mixing_beta) mixing_beta_new = mixing_beta * factor self.ctx.restart_calc = None self.ctx.inputs.parameters.setdefault('ELECTRONS', {})['mixing_beta'] = mixing_beta_new self.ctx.inputs.structure = calculation.outputs.output_structure action = 'no electronic convergence but clean shutdown: reduced beta mixing from {} to {} restarting from ' \ 'scratch but using output structure.'.format(mixing_beta, mixing_beta_new) self.report_error_handled(calculation, action) return ErrorHandlerReport(True, True)
def _handle_unrecoverable_failure(self, calculation): """Calculations with an exit status below 400 are unrecoverable, so abort the work chain.""" if calculation.exit_status < 400: self.report_error_handled(calculation, 'unrecoverable error, aborting...') return ErrorHandlerReport(True, True, self.exit_codes.ERROR_UNRECOVERABLE_FAILURE)
def _handle_out_of_walltime(self, calculation): """In the case of `ERROR_OUT_OF_WALLTIME` calculation shut down neatly and we can simply restart.""" if calculation.exit_status == PhCalculation.exit_codes.ERROR_OUT_OF_WALLTIME.status: self.ctx.restart_calc = calculation self.report_error_handled(calculation, 'simply restart from the last calculation') return ErrorHandlerReport(True, True)