Ejemplo n.º 1
0
    def check_failure(self):
        """
        Throws an exit code if scf failed
        """
        try:
            scf_wc = self.ctx.scf_res
        except AttributeError:
            message = 'ERROR: Something went wrong I do not have new atom positions calculation'
            self.control_end_wc(message)
            return self.exit_codes.ERROR_NO_SCF_OUTPUT

        if not scf_wc.is_finished_ok:
            exit_statuses = FleurScfWorkChain.get_exit_statuses(
                ['ERROR_FLEUR_CALCULATION_FAILED'])
            if scf_wc.exit_status == exit_statuses[0]:
                fleur_calc = load_node(
                    scf_wc.outputs.output_scf_wc_para.get_dict()
                    ['last_calc_uuid'])
                if fleur_calc.exit_status == FleurCalc.get_exit_statuses(
                    ['ERROR_VACUUM_SPILL_RELAX'])[0]:
                    self.control_end_wc(
                        'ERROR: Failed due to atom and vacuum overlap')
                    return self.exit_codes.ERROR_VACUUM_SPILL_RELAX
                elif fleur_calc.exit_status == FleurCalc.get_exit_statuses(
                    ['ERROR_MT_RADII_RELAX'])[0]:
                    self.control_end_wc('ERROR: Failed due to MT overlap')
                    return self.exit_codes.ERROR_MT_RADII_RELAX
            return self.exit_codes.ERROR_SCF_FAILED
Ejemplo n.º 2
0
    def return_results(self):
        """
        return the results of the relaxed DFT+U calculations (scf workchains)
        """
        distancelist = []
        t_energylist = []
        failed_configs = []
        non_converged_configs = []
        configs_list = []
        outnodedict = {}

        e_u = 'htr'
        dis_u = 'me/bohr^3'
        for index, config in enumerate(self.ctx.fixed_configurations):
            if f'Relaxed_{index}' in self.ctx:
                calc = self.ctx[f'Relaxed_{index}']
            else:
                message = (
                    'One SCF workflow was not run because the fixed calculation failed: {}'.format(f'Relaxed_{index}'))
                self.ctx.warnings.append(message)
                self.ctx.successful = False
                failed_configs.append(index)
                continue

            if not calc.is_finished_ok:
                message = ('One SCF workflow was not successful: {}'.format(f'Relaxed_{index}'))
                self.ctx.warnings.append(message)
                self.ctx.successful = False
                #We dont skip simply non-converged calculations
                #because we want to try to exctract the total_energy
                if calc.exit_status not in FleurScfWorkChain.get_exit_statuses(['ERROR_DID_NOT_CONVERGE']):
                    failed_configs.append(index)
                    continue
                non_converged_configs.append(index)

            try:
                outputnode_scf = calc.outputs.output_scf_wc_para
            except KeyError:
                message = ('One SCF workflow failed, no scf output node: {}.'
                           ' I skip this one.'.format(f'Relaxed_{index}'))
                self.ctx.errors.append(message)
                self.ctx.successful = False
                failed_configs.append(index)
                continue

            try:
                fleurinp_scf = calc.outputs.fleurinp
            except KeyError:
                message = ('One SCF workflow failed, no fleurinp output node: {}.'
                           ' I skip this one.'.format(f'Relaxed_{index}'))
                self.ctx.errors.append(message)
                self.ctx.successful = False
                failed_configs.append(index)
                continue

            # we loose the connection of the failed scf here.
            # link labels cannot contain '.'
            link_label = f'configuration_{index}'
            fleurinp_label = f'fleurinp_{index}'
            outnodedict[link_label] = outputnode_scf
            outnodedict[fleurinp_label] = fleurinp_scf

            outpara = outputnode_scf.get_dict()

            t_e = outpara.get('total_energy', float('nan'))
            e_u = outpara.get('total_energy_units', 'htr')
            dis = outpara.get('distance_charge', float('nan'))
            dis_u = outpara.get('distance_charge_units', 'me/bohr^3')
            t_energylist.append(t_e)
            distancelist.append(dis)
            configs_list.append(index)

        out = {
            'workflow_name': self.__class__.__name__,
            'workflow_version': self._workflowversion,
            'configurations': self.ctx.fixed_configurations,
            'total_energy': t_energylist,
            'total_energy_units': e_u,
            'distance_charge': distancelist,
            'distance_charge_units': dis_u,
            'successful_configs': configs_list,
            'non_converged_configs': non_converged_configs,
            'failed_configs': failed_configs,
            'info': self.ctx.info,
            'warnings': self.ctx.warnings,
            'errors': self.ctx.errors
        }

        if self.ctx.successful:
            self.report('Done, Orbital occupation control calculation complete')
        elif len(t_energylist) != 0:
            self.report('Done, but something went wrong.... Probably some individual calculation failed or'
                        ' a scf-cycle did not reach the desired distance.')
        else:
            self.report('Done, but something went wrong.... All Calculations failed. Probably something is'
                        ' wrong in your setup')

        outnode = Dict(dict=out)
        outnodedict['results_node'] = outnode

        # create links between all these nodes...
        outputnode_dict = create_orbcontrol_result_node(**outnodedict)
        outputnode = outputnode_dict.get('output_orbcontrol_wc_para')
        outputnode.label = 'output_orbcontrol_wc_para'
        outputnode.description = (
            'Contains orbital occupation control results and information of an FleurOrbControlWorkChain run.')

        returndict = {}
        returndict['output_orbcontrol_wc_para'] = outputnode

        outputscf = outputnode_dict.get('output_orbcontrol_wc_gs_scf', None)
        if outputscf:
            outputscf.label = 'output_orbcontrol_wc_gs_scf'
            outputscf.description = ('SCF output from the run with the lowest total '
                                     'energy extracted from FleurOrbControlWorkChain')

            returndict['output_orbcontrol_wc_gs_scf'] = outputscf

        outputfleurinp = outputnode_dict.get('output_orbcontrol_wc_gs_fleurinp', None)
        if outputscf:
            outputscf.label = 'output_orbcontrol_wc_gs_fleurinp'
            outputscf.description = ('Fleurinp from the scf run with the lowest total '
                                     'energy extracted from FleurOrbControlWorkChain')

            returndict['output_orbcontrol_wc_gs_fleurinp'] = outputfleurinp

        # create link to workchain node
        for link_name, node in returndict.items():
            self.out(link_name, node)

        if len(t_energylist) == 0:
            return self.exit_codes.ERROR_ALL_CONFIGS_FAILED
        elif not self.ctx.successful:
            return self.exit_codes.ERROR_SOME_CONFIGS_FAILED