def run_relax(self): """Run the `PwBaseWorkChain` to run a relax `PwCalculation`.""" self.ctx.iteration += 1 inputs = AttributeDict( self.exposed_inputs(PwBaseWorkChain, namespace='base')) inputs.pw.structure = self.ctx.current_structure inputs.pw.parameters = inputs.pw.parameters.get_dict() inputs.pw.parameters.setdefault('CELL', {}) inputs.pw.parameters.setdefault('CONTROL', {}) inputs.pw.parameters['CONTROL']['restart_mode'] = 'from_scratch' if 'relaxation_scheme' in self.inputs: if self.inputs.relaxation_scheme.value == 'relax': relax_type = RelaxType.ATOMS elif self.inputs.relaxation_scheme.value == 'vc-relax': relax_type = RelaxType.ATOMS_CELL else: raise ValueError( 'unsupported value for the `relaxation_scheme` input.') else: relax_type = RelaxType(self.inputs.relax_type) if relax_type in [ RelaxType.NONE, RelaxType.VOLUME, RelaxType.SHAPE, RelaxType.CELL ]: inputs.pw.settings = self._fix_atomic_positions( inputs.pw.structure, inputs.pw.get('settings', None)) if relax_type in [RelaxType.NONE, RelaxType.ATOMS]: inputs.pw.parameters['CONTROL']['calculation'] = 'relax' inputs.pw.parameters.pop('CELL', None) else: inputs.pw.parameters['CONTROL']['calculation'] = 'vc-relax' if relax_type in [RelaxType.VOLUME, RelaxType.ATOMS_VOLUME]: inputs.pw.parameters['CELL']['cell_dofree'] = 'volume' if relax_type in [RelaxType.SHAPE, RelaxType.ATOMS_SHAPE]: inputs.pw.parameters['CELL']['cell_dofree'] = 'shape' if relax_type in [RelaxType.CELL, RelaxType.ATOMS_CELL]: inputs.pw.parameters['CELL']['cell_dofree'] = 'all' # If one of the nested `PwBaseWorkChains` changed the number of bands, apply it here if self.ctx.current_number_of_bands is not None: inputs.pw.parameters.setdefault( 'SYSTEM', {})['nbnd'] = self.ctx.current_number_of_bands # Set the `CALL` link label inputs.metadata.call_link_label = f'iteration_{self.ctx.iteration:02d}' inputs = prepare_process_inputs(PwBaseWorkChain, inputs) running = self.submit(PwBaseWorkChain, **inputs) self.report(f'launching PwBaseWorkChain<{running.pk}>') return ToContext(workchains=append_(running))
def run_raspa_gcmc(self): """ It submits Raspa calculation to RaspaBaseWorkchain. """ self.ctx.current_p_index = 0 self.ctx.pressures = get_pressure_list(self.ctx.parameters) self.report( "<{}> pressure points are chosen for GCMC calculations".format( len(self.ctx.pressures))) self.ctx.raspa_params, self.ctx.raspa_inputs = self._update_param_input_for_gcmc( ) self.ctx.raspa_inputs['metadata'][ 'description'] = 'Called by HTSWorkChain' for index, pressure in enumerate(self.ctx.pressures): self.ctx.raspa_inputs['metadata']['label'] = "RaspaGCMC_{}".format( index + 1) self.ctx.raspa_inputs['metadata'][ 'call_link_label'] = "run_raspa_gcmc_{}".format(index + 1) self.ctx.raspa_params["System"][self.inputs.structure.label][ "ExternalPressure"] = self.ctx.pressures[index] * 1e5 self.ctx.raspa_inputs['raspa']['parameters'] = Dict( dict=self.ctx.raspa_params) running = self.submit(RaspaBaseWorkChain, **self.ctx.raspa_inputs) self.report( "Running Raspa GCMC @ {}K/{:.3f}bar (pressure {} of {})". format(self.ctx.temperature, self.ctx.pressures[index], index + 1, len(self.ctx.pressures))) self.to_context(raspa_gcmc=append_(running))
def run_scf_smearing(self): """ Run a simple PwCalculation with smeared occupations """ inputs = copy(self.ctx.inputs) inputs.parameters = deepcopy(inputs.parameters) inputs.parameters['CONTROL']['calculation'] = 'scf' inputs.parameters['SYSTEM']['occupations'] = 'smearing' inputs.parameters['SYSTEM']['smearing'] = inputs.parameters[ 'SYSTEM'].get('smearing', self.defaults.smearing_method) inputs.parameters['SYSTEM']['degauss'] = inputs.parameters[ 'SYSTEM'].get('degauss', self.defaults.smearing_degauss) inputs.parameters['SYSTEM']['u_projection_type'] = inputs.parameters[ 'SYSTEM'].get('u_projection_type', self.defaults.u_projection_type_scf) inputs.parameters['ELECTRONS']['conv_thr'] = inputs.parameters[ 'ELECTRONS'].get('conv_thr', self.defaults.conv_thr_preconverge) inputs.parameters = ParameterData(dict=inputs.parameters) running = self.submit(PwBaseWorkChain, **inputs) self.report( 'launching PwBaseWorkChain<{}> with smeared occupations'.format( running.pk)) return ToContext(workchains_scf=append_(running))
def run_relax(self): """ Run the PwRelaxWorkChain to run a relax PwCalculation """ inputs = copy(self.ctx.inputs) inputs.parameters = deepcopy(inputs.parameters) u_projection_type_relax = inputs.parameters['SYSTEM'].get( 'u_projection_type', self.defaults.u_projection_type_relax) if u_projection_type_relax != self.defaults.u_projection_type_relax: self.report( "warning: you specified 'u_projection_type = {}' in the input parameters, but this will crash " "pw.x, changing it to '{}'".format( u_projection_type_relax, self.defaults.u_projection_type_relax)) inputs.parameters['SYSTEM'][ 'u_projection_type'] = self.defaults.u_projection_type_relax inputs.parameters = ParameterData(dict=inputs.parameters) running = self.submit(PwRelaxWorkChain, **inputs) self.report('launching PwRelaxWorkChain<{}> iteration #{}'.format( running.pk, self.ctx.iteration)) return ToContext(workchains_relax=append_(running))
def run_calculation(self): """Run the next calculation, taking the input dictionary from the context at `self.ctx.inputs`.""" from aiida_quantumespresso.utils.mapping import prepare_process_inputs self.ctx.iteration += 1 try: unwrapped_inputs = self.ctx.inputs except AttributeError: raise AttributeError('no calculation input dictionary was defined in `self.ctx.inputs`') # Set the `CALL` link label unwrapped_inputs['metadata']['call_link_label'] = 'iteration_{:02d}'.format(self.ctx.iteration) inputs = prepare_process_inputs(self._calculation_class, unwrapped_inputs) calculation = self.submit(self._calculation_class, **inputs) # Add a new empty list to the `errors_handled` extra. If any errors handled registered through the # `register_error_handler` decorator return an `ErrorHandlerReport`, their name will be appended to that list. errors_handled = self.node.get_extra('errors_handled', []) errors_handled.append([]) self.node.set_extra('errors_handled', errors_handled) self.report('launching {}<{}> iteration #{}'.format(self.ctx.calc_name, calculation.pk, self.ctx.iteration)) return ToContext(calculations=append_(calculation))
def run_relax(self): """Run the `PwBaseWorkChain` to run a relax `PwCalculation`.""" self.ctx.iteration += 1 inputs = AttributeDict(self.exposed_inputs(PwBaseWorkChain, namespace='base')) inputs.pw.structure = self.ctx.current_structure inputs.pw.parameters = inputs.pw.parameters.get_dict() inputs.pw.parameters.setdefault('CONTROL', {}) inputs.pw.parameters['CONTROL']['calculation'] = self.inputs.relaxation_scheme.value inputs.pw.parameters['CONTROL']['restart_mode'] = 'from_scratch' # If one of the nested `PwBaseWorkChains` changed the number of bands, apply it here if self.ctx.current_number_of_bands is not None: inputs.pw.parameters.setdefault('SYSTEM', {})['nbnd'] = self.ctx.current_number_of_bands # Set the `CALL` link label inputs.metadata.call_link_label = 'iteration_{:02d}'.format(self.ctx.iteration) inputs = prepare_process_inputs(PwBaseWorkChain, inputs) running = self.submit(PwBaseWorkChain, **inputs) self.report('launching PwBaseWorkChain<{}>'.format(running.pk)) return ToContext(workchains=append_(running))
def run_raspa_gcmc(self): """ It submits Raspa calculation to RaspaBaseWorkchain. """ self.ctx.raspa_params, self.ctx.raspa_inputs = self._update_param_input_for_gcmc( ) self.ctx.raspa_inputs['metadata'][ 'description'] = 'Called by MultiCompIsothermWorkChain' self.ctx.raspa_inputs['metadata']['label'] = "RaspaGCMC_{}".format( self.ctx.current_p_index + 1) self.ctx.raspa_inputs['metadata'][ 'call_link_label'] = "run_raspa_gcmc_{}".format( self.ctx.current_p_index + 1) self.ctx.raspa_params["System"][self.inputs.structure.label][ "ExternalPressure"] = self.ctx.pressures[ self.ctx.current_p_index] * 1e5 self.ctx.raspa_inputs['raspa']['parameters'] = Dict( dict=self.ctx.raspa_params) if self.ctx.current_p_index > 0: self.ctx.raspa_inputs['raspa'][ 'retrieved_parent_folder'] = self.ctx.raspa_gcmc[ self.ctx.current_p_index - 1].outputs.retrieved running = self.submit(RaspaBaseWorkChain, **self.ctx.raspa_inputs) self.report( "Running Raspa GCMC @ {}K/{:.3f}bar (pressure {} of {})".format( self.ctx.temperature, self.ctx.pressures[self.ctx.current_p_index], self.ctx.current_p_index + 1, len(self.ctx.pressures))) self.ctx.current_p_index += 1 return ToContext(raspa_gcmc=append_(running))
def run_stage(self): """Check for restart, prepare input, submit and direct output to context.""" # Update structure self.ctx.base_inp['cp2k']['structure'] = self.ctx.structure # Check if it is needed to restart the calculation and provide the parent folder and new structure if self.ctx.parent_calc_folder: self.ctx.base_inp['cp2k']['parent_calc_folder'] = self.ctx.parent_calc_folder self.ctx.cp2k_param['FORCE_EVAL']['DFT']['SCF']['SCF_GUESS'] = 'RESTART' self.ctx.cp2k_param['FORCE_EVAL']['DFT']['WFN_RESTART_FILE_NAME'] = './parent_calc/aiida-RESTART.wfn' else: self.ctx.cp2k_param['FORCE_EVAL']['DFT']['SCF']['SCF_GUESS'] = 'ATOMIC' # Overwrite the generated input with the custom cp2k/parameters if 'parameters' in self.exposed_inputs(Cp2kBaseWorkChain, 'cp2k_base')['cp2k']: merge_dict( self.ctx.cp2k_param, AttributeDict(self.exposed_inputs(Cp2kBaseWorkChain, 'cp2k_base')['cp2k']['parameters'].get_dict())) self.ctx.base_inp['cp2k']['parameters'] = Dict(dict=self.ctx.cp2k_param).store() # Update labels self.ctx.base_inp['metadata'].update({ 'label': '{}_{}'.format(self.ctx.stage_tag, self.ctx.settings_tag), 'call_link_label': 'run_{}_{}'.format(self.ctx.stage_tag, self.ctx.settings_tag), }) self.ctx.base_inp['cp2k']['metadata'].update( {'label': self.ctx.base_inp['cp2k']['parameters'].get_dict()['GLOBAL']['RUN_TYPE']}) running_base = self.submit(Cp2kBaseWorkChain, **self.ctx.base_inp) self.report("submitted Cp2kBaseWorkChain for {}/{}".format(self.ctx.stage_tag, self.ctx.settings_tag)) return ToContext(stages=append_(running_base))
def run_pp(self, spin): """The inputs to run the post-processing calculations Parameters: ----------- spin: 'up'=for spin-up calculations 'dn'=for spin-down calculations Returns: -------- """ #PpCalculation = CalculationFactory('quantumespresso.pp') inputs = self.exposed_inputs(PpCalculation, namespace='pp') inputs['parent_folder'] = self.ctx.current_parent_folder inputs['parameters'] = orm.Dict( dict={ 'INPUTPP': { 'plot_num': 17, 'spin_component': 1 if spin == 'up' else 2 }, 'PLOT': { 'iflag': 3 } }) running = self.submit(PpCalculation, **inputs) self.report('launching PPCalculation<{}>'.format(running.pk)) return ToContext(workchains=append_(running))
def run_raspa_gcmc(self): """Run a GCMC calculation in Raspa @ T,P. """ # Update labels self.ctx.inp['metadata']['label'] = "RaspaGCMC_{}".format(self.ctx.current_p_index + 1) self.ctx.inp['metadata']['call_link_label'] = "run_raspa_gcmc_{}".format(self.ctx.current_p_index + 1) # Update pressure (NOTE: need to convert from bar to Pa) self.ctx.raspa_param["System"]["framework_1"]['ExternalPressure'] = \ self.ctx.pressures[self.ctx.current_p_index] * 1e5 # Update parameters Dict self.ctx.inp['raspa']['parameters'] = Dict(dict=self.ctx.raspa_param) # Update restart (if present, i.e., if current_p_index>0) if self.ctx.current_p_index > 0: self.ctx.inp['raspa']['retrieved_parent_folder'] = self.ctx.raspa_gcmc[self.ctx.current_p_index - 1].outputs.retrieved # Create the calculation process, launch it and update pressure index running = self.submit(RaspaBaseWorkChain, **self.ctx.inp) self.report("Running Raspa GCMC {} @ {}K/{:.3f}bar (pressure {} of {})".format( self.ctx.molecule['name'], self.ctx.temperature, self.ctx.pressures[self.ctx.current_p_index], self.ctx.current_p_index + 1, len(self.ctx.pressures))) self.ctx.current_p_index += 1 return ToContext(raspa_gcmc=append_(running))
def run_atoms(self): """ Run a separate HpBaseWorkChain for each of the defined Hubbard atoms """ workchain = self.ctx.initialization if not workchain.is_finished_ok: self.report('initialization workchain<{}> failed with finish status {}, aborting...' .format(workchain.pk, workchain.finish_status)) return self.ERROR_CHILD_WORKCHAIN_FAILED output_params = workchain.out.output_parameters.get_dict() hubbard_sites = output_params['hubbard_sites'] for site_index, site_kind in hubbard_sites.iteritems(): do_only_key = 'do_one_only({})'.format(site_index) inputs = AttributeDict(self.exposed_inputs(HpBaseWorkChain)) inputs.parameters = inputs.parameters.get_dict() inputs.parameters['INPUTHP'][do_only_key] = True inputs.parameters = ParameterData(dict=inputs.parameters) running = self.submit(HpBaseWorkChain, **inputs) self.report('launching HpBaseWorkChain<{}> for atomic site {} of kind {}'.format(running.pk, site_index, site_kind)) self.to_context(workchains=append_(running))
def run_init(self): """Run the first workchain.""" scale_factor = self.get_scale_factors()[0] builder = self.get_sub_workchain_builder(scale_factor) self.report(f'submitting `{builder.process_class.__name__}` for scale_factor `{scale_factor}`') self.ctx.previous_workchain = self.submit(builder) self.to_context(children=append_(self.ctx.previous_workchain))
def run_geo_opt(self): """Prepare inputs, submit and direct output to context.""" self.ctx.base_inp = AttributeDict( self.exposed_inputs(Cp2kBaseWorkChain, 'cp2k_base')) self.ctx.base_inp['cp2k']['structure'] = self.ctx.system # Overwrite the generated input with the custom cp2k/parameters, update metadata and submit if 'parameters' in self.exposed_inputs(Cp2kBaseWorkChain, 'cp2k_base')['cp2k']: dict_merge( self.ctx.cp2k_param, self.exposed_inputs( Cp2kBaseWorkChain, 'cp2k_base')['cp2k']['parameters'].get_dict()) self.ctx.base_inp['cp2k']['parameters'] = Dict( dict=self.ctx.cp2k_param) self.ctx.base_inp['metadata'].update({ 'label': 'geo_opt_molecule', 'call_link_label': 'run_geo_opt_molecule' }) self.ctx.base_inp['cp2k']['metadata'].update({'label': 'GEO_OPT'}) self.ctx.base_inp['cp2k']['metadata']['options'][ 'parser_name'] = 'lsmo.cp2k_advanced_parser' running_base = self.submit(Cp2kBaseWorkChain, **self.ctx.base_inp) self.report("Optimize molecule position in the structure.") return ToContext(stages=append_(running_base))
def relax(self): self.ctx.inputs = AttributeDict( self.exposed_inputs(BigDFTBaseWorkChain)) inputdict = self.inputs.parameters.dict if self.inputs.relax.perform: InputActions.optimize_geometry(inputdict, self.inputs.relax.algo.value, self.inputs.relax.steps.value) if self.inputs.relax.threshold_forces is not None: InputActions.dict_set(inputdict, 'geopt', 'forcemax', self.inputs.relax.threshold_forces.value / HARTREE_BOHR_TO_EV_AG) self.ctx.inputs.parameters = BigDFTParameters(dict=inputdict) # gather outputs extra_retrieved_files = List() if self.inputs.extra_retrieved_files is not None: extra_retrieved_files.set_list( self.inputs.extra_retrieved_files.get_list()) extension = "xyz" posinp = self.inputs.parameters.dict.get('posinp') if posinp is not None: try: extension = posinp['properties']['format'] except KeyError: extension = "yaml" extra_retrieved_files.extend([["./data*/*." + extension, ".", 2], ["./data*/geopt.mon", ".", 2], ["./final_*", ".", 2]]) self.ctx.inputs.extra_retrieved_files = extra_retrieved_files node = self.submit(BigDFTBaseWorkChain, **self.ctx.inputs) return ToContext(work=append_(node))
def get_gc_data(self): """Get the gc data.""" inputs = self.ctx.inputs running = self.submit(self._calculation, **inputs) self.report('fetching gc data using {}<{}> '.format(self._calculation.__name__, running.pk)) return self.to_context(calculations=append_(running))
def run_eos(self): """Run the sub process at each scale factor to compute the structure volume and total energy.""" for scale_factor in self.get_scale_factors()[1:]: reference_workchain = self.ctx.reference_workchain builder, structure = self.get_sub_workchain_builder(scale_factor, reference_workchain=reference_workchain) self.report(f'submitting `{builder.process_class.__name__}` for scale_factor `{scale_factor}`') self.ctx.structures.append(structure) self.to_context(children=append_(self.submit(builder)))
def run_dissociation(self): """Run the sub process at each distance to compute the total energy.""" for distance in self.get_distances()[1:]: previous_workchain = self.ctx.previous_workchain builder, distance_node = self.get_sub_workchain_builder(distance, previous_workchain=previous_workchain) self.ctx.distance_nodes.append(distance_node) self.report(f'submitting `{builder.process_class.__name__}` for dinstance `{distance.value}`') self.to_context(children=append_(self.submit(builder)))
def run_init(self): """Run the first workchain.""" scale_factor = orm.Float(self.get_scale_factors()[0]) builder, structure = self.get_sub_workchain_builder(scale_factor) self.report(f'submitting `{builder.process_class.__name__}` for scale_factor `{scale_factor}`') self.ctx.reference_workchain = self.submit(builder) self.ctx.structures = [structure] self.to_context(children=append_(self.ctx.reference_workchain))
def run_init(self): """Run the first workchain.""" distance = self.get_distances()[0] builder, distance_node = self.get_sub_workchain_builder(distance) self.ctx.distance_nodes = [distance_node] self.report(f'submitting `{builder.process_class.__name__}` for distance `{distance.value}`') self.ctx.previous_workchain = self.submit(builder) self.to_context(children=append_(self.ctx.previous_workchain))
def run_next_workchain(self): """Run the next workchain.""" inputs = self.ctx.inputs running = self.submit(self._next_workchain, **inputs) self.report('launching {}<{}> iteration #{}'.format( self._next_workchain.__name__, running.pk, self.ctx.iteration)) return self.to_context(workchains=append_(running))
def do_submit(self): if self.should_submit(): self.report('Submitting nested workchain.') return ToContext( workchain=append_(self.submit( NestedWorkChain, inp=self.inputs.inp - 1 )) )
def run_init_scf(self): """ Run initial scf calculation """ self.ctx.iteration += 1 parameters = self.update_builder_parameters() self.ctx.restart_builder.parameters = orm.Dict(dict=parameters) running = self.submit(self.ctx.restart_builder) self.report('launching PwBaseWorkChain<{}> in {} mode'.format( running.pk, 'scf')) #return self.to_context(workchain_init_scf=append_(running)) return ToContext(workchain_init_scf=append_(running))
def run_next_workchain(self): """ Run the next workchain It is either submitted to the daemon or run, depending on how you run this workchain. The execution method is inherited. """ inputs = self.ctx.inputs running = self.submit(self._next_workchain, **inputs) self.report('launching {}<{}> iteration #{}'.format(self._next_workchain.__name__, running.pk, self.ctx.iteration)) return self.to_context(workchains=append_(running))
def run_next_workchain(self): """Run the next workchain.""" inputs = self.ctx.inputs_ready running = self.submit(self._next_workchain, **inputs) if not self.ctx.is_converged and self.perform_relaxation(): self.report('launching {}<{}> iteration #{}'.format( self._next_workchain.__name__, running.pk, self.ctx.iteration)) else: self.report('launching {}<{}> '.format( self._next_workchain.__name__, running.pk)) return self.to_context(workchains=append_(running))
def scf_next_workchain(self): """Initialize and Run the next workchain""" self.ctx.iteration += 1 parameters = self.update_builder_parameters() self.ctx.inputs.parameters = orm.Dict(dict=parameters) self.ctx.inputs.parameters.store() running = self.submit(self.ctx.inputs) #running = self.submit(self.ctx.restart_builder) self.report( 'running PwBaseWorkChain<{}> calculation for equiv. {} with position {}' .format(running.pk, self.ctx.label, self.ctx.mupos)) #return self.to_context(workchain_equiv=append_(running)) return ToContext(workchain_equiv=append_(running))
def run_bands(self): """Run the band calculation.""" self.ctx.iteration += 1 inputs = self.ctx.inputs inputs.kpoints = self.ctx.current_kpoints inputs = prepare_process_inputs(PwBaseWorkChain, inputs) running = self.submit(PwBaseWorkChain, **inputs) self.report( 'launching PwBaseWorkChain<{}> in {} mode, iteration {}'.format( running.pk, 'bands', self.ctx.iteration)) return ToContext(workchain_bands=append_(running))
def run_final(self): """ Perform the final HpCalculation to collect the various components of the chi matrices """ inputs = AttributeDict(self.exposed_inputs(HpBaseWorkChain)) inputs.parameters = inputs.parameters.get_dict() inputs.parameters['INPUTHP']['collect_chi'] = True inputs.parameters = ParameterData(dict=inputs.parameters) inputs.parent_folder = self.ctx.merged_retrieved inputs.pop('parent_calculation', None) running = self.submit(HpBaseWorkChain, **inputs) self.report('launching HpBaseWorkChain<{}> to collect matrices'.format(running.pk)) self.to_context(workchains=append_(running))
def run_projwfc(self): inputs = self.exposed_inputs(PjwfcCalculation, namespace='projwfc') inputs['parent_folder'] = self.ctx.current_parent_folder inputs['parameters'] = orm.Dict( dict={'PROJWFC': { 'DeltaE': 0.2, 'ngauss': 1, 'degauss': 0.02 }}) running = self.submit(PjwfcCalculation, **inputs) self.report('launching ProjWfcCalculation<{}>'.format(running.pk)) return ToContext(workchains=append_(running))
def run_calculation(self): """Run the next calculation, taking the input dictionary from the context at `self.ctx.inputs`.""" from aiida_fleur.common.mapping import prepare_process_inputs self.ctx.iteration += 1 try: unwrapped_inputs = self.ctx.inputs except AttributeError as exc: raise AttributeError('no calculation input dictionary was defined in `self.ctx.inputs`') from exc inputs = prepare_process_inputs(self._calculation_class, unwrapped_inputs) calculation = self.submit(self._calculation_class, **inputs) self.report('launching {}<{}> iteration #{}'.format( self.ctx.calc_name, calculation.pk, self.ctx.iteration)) return ToContext(calculations=append_(calculation))
def run_hp(self): """ Run the HpWorkChain restarting from the last completed scf calculation """ self.ctx.iteration += 1 workchain = self.ctx.workchains_scf[-1] parent_calculation = workchain.out.output_parameters.get_inputs( node_type=PwCalculation)[0] inputs = self.exposed_inputs(HpWorkChain, namespace='hp') inputs['parent_calculation'] = parent_calculation running = self.submit(HpWorkChain, **inputs) self.report('launching HpWorkChain<{}> iteration #{}'.format( running.pk, self.ctx.iteration)) return ToContext(workchains_hp=append_(running))