def run_wannier90(self): try: remote_folder = self.ctx.calc_pw2wannier90.outputs.remote_folder except AttributeError: self.report( 'the Pw2wannier90Calculation did not output a remote_folder node' ) return self.exit_codes.ERROR_SUB_PROCESS_FAILED_WANNIER90 # we need metadata in exposed_inputs inputs = AttributeDict( self.exposed_inputs(Wannier90Calculation, namespace='wannier90')) pp_inputs = self.ctx.calc_wannier90_pp.inputs pp_keys = [ 'code', 'parameters', 'kpoint_path', 'structure', 'kpoints', 'settings' ] for key in pp_keys: inputs[key] = pp_inputs[key] inputs['remote_input_folder'] = remote_folder settings = inputs.settings.get_dict() settings['postproc_setup'] = False inputs.settings = settings inputs = prepare_process_inputs(Wannier90Calculation, inputs) running = self.submit(Wannier90Calculation, **inputs) self.report( 'wannier90 step - launching Wannier90Calculation<{}>'.format( running.pk)) return ToContext(calc_wannier90=running)
def run_relax(self): """ Run the PwRelaxWorkChain to run a relax calculation """ inputs = AttributeDict( self.exposed_inputs(PwRelaxWorkChain, namespace='relax')) inputs.structure = self.ctx.current_structure running = self.submit(PwRelaxWorkChain, **inputs) self.report('launching PwRelaxWorkChain<{}>'.format(running.pk)) return ToContext(workchain_relax=running)
def run_pw2wannier90(self): inputs = AttributeDict( self.exposed_inputs(Pw2wannier90Calculation, namespace='pw2wannier90')) try: remote_folder = self.ctx.workchain_nscf.outputs.remote_folder except AttributeError: return self.exit_codes.ERROR_SUB_PROCESS_FAILED_PW2WANNIER90( 'the nscf WorkChain did not output a remote_folder node') inputs['parent_folder'] = remote_folder inputs['nnkp_file'] = self.ctx.calc_wannier90_pp.outputs.nnkp_file inputs.parameters = inputs.parameters.get_dict() inputs.parameters['inputpp'].update({ 'write_mmn': True, 'write_amn': True, }) if self.ctx.auto_projections: inputs.parameters['inputpp']['scdm_proj'] = True # TODO: if exclude_band: gaussian # TODO: auto check if is insulator? if self.inputs.only_valence: inputs.parameters['inputpp']['scdm_entanglement'] = 'isolated' else: inputs.parameters['inputpp']['scdm_entanglement'] = 'erfc' try: inputs.parameters = update_pw2wan_params_mu_sigma( parameters=orm.Dict(dict=inputs.parameters), wannier_parameters=self.ctx.calc_wannier90_pp.inputs. parameters, bands=self.ctx.calc_projwfc.outputs.bands, projections=self.ctx.calc_projwfc.outputs.projections, thresholds=self.inputs.get('scdm_thresholds')) except ValueError: self.report( 'WARNING: update_pw2wan_params_mu_sigma failed!') return self.exit_codes.ERROR_SUB_PROCESS_FAILED_PW2WANNIER90 inputs = prepare_process_inputs(Pw2wannier90Calculation, inputs) running = self.submit(Pw2wannier90Calculation, **inputs) self.report( 'pw2wannier90 step - launching Pw2Wannier90Calculation<{}>'.format( running.pk)) return ToContext(calc_pw2wannier90=running)
def run_projwfc(self): """ Projwfc step :return: """ inputs = AttributeDict( self.exposed_inputs(ProjwfcCalculation, namespace='projwfc')) inputs.parent_folder = self.ctx.current_folder inputs = prepare_process_inputs(ProjwfcCalculation, inputs) running = self.submit(ProjwfcCalculation, **inputs) self.report('projwfc step - launching ProjwfcCalculation<{}>'.format( running.pk)) return ToContext(calc_projwfc=running)
def run_scf(self): """ Run the PwBaseWorkChain in scf mode on the primitive cell of (optionally relaxed) input structure. """ inputs = AttributeDict( self.exposed_inputs(PwBaseWorkChain, namespace='scf')) 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'] = 'scf' inputs = prepare_process_inputs(PwBaseWorkChain, inputs) running = self.submit(PwBaseWorkChain, **inputs) self.report( 'scf step - launching PwBaseWorkChain<{}> in {} mode'.format( running.pk, 'scf')) return ToContext(workchain_scf=running)
def run_wannier90_pp(self): """The input of wannier90 calculation is build here. :return: [description] :rtype: [type] """ inputs = AttributeDict( self.exposed_inputs(Wannier90Calculation, namespace='wannier90')) inputs.structure = self.ctx.current_structure parameters = inputs.parameters.get_dict() # get nscf kmesh inputs.kpoints = self.ctx.workchain_nscf.inputs.kpoints # the input kpoints of nscf is an explicitly generated list of kpoints, # we mush retrieve the original kmesh, and explicitly set w90 mp_grid keyword parameters['mp_grid'] = self.ctx.nscf_kmesh.get_kpoints_mesh()[0] # check num_bands, exclude_bands, nscf nbnd nbnd = self.ctx.workchain_nscf.outputs.output_parameters.get_dict( )['number_of_bands'] num_ex_bands = len(get_exclude_bands(inputs.parameters.get_dict())) parameters['num_bands'] = nbnd - num_ex_bands # set num_wann for auto_projections if self.ctx.auto_projections: if self.inputs.only_valence: parameters['num_wann'] = parameters['num_bands'] inputs.parameters = orm.Dict(dict=parameters) else: inputs.parameters = orm.Dict(dict=parameters) inputs.parameters = update_w90_params_numwann( inputs.parameters, self.ctx.calc_projwfc.outputs.projections) self.report( 'number of Wannier functions extracted from projections: ' + str(inputs.parameters['num_wann'])) # get scf Fermi energy try: energies_relative_to_fermi = self.inputs.get( 'wannier_energies_relative_to_fermi') inputs.parameters = update_w90_params_fermi( inputs.parameters, self.ctx.workchain_scf.outputs.output_parameters, energies_relative_to_fermi) except TypeError: self.report("Error in retriving the SCF Fermi energy " "from pk: {}".format(self.ctx.workchain_scf)) return self.exit_codes.ERROR_SUB_PROCESS_FAILED_WANNIER90PP #Check if settings is given in input try: settings = inputs['settings'].get_dict() except KeyError: settings = {} settings['postproc_setup'] = True inputs['settings'] = settings inputs = prepare_process_inputs(Wannier90Calculation, inputs) running = self.submit(Wannier90Calculation, **inputs) self.report( 'wannier90 postproc step - launching Wannier90Calculation<{}> in postproc mode' .format(running.pk)) return ToContext(calc_wannier90_pp=running)
def run_nscf(self): """ Run the PwBaseWorkChain in nscf mode """ inputs = AttributeDict( self.exposed_inputs(PwBaseWorkChain, namespace='nscf')) inputs.pw.structure = self.ctx.current_structure inputs.pw.parent_folder = self.ctx.current_folder inputs.pw.parameters = inputs.pw.parameters.get_dict() inputs.pw.parameters.setdefault('CONTROL', {}) inputs.pw.parameters.setdefault('SYSTEM', {}) inputs.pw.parameters.setdefault('ELECTRONS', {}) inputs.pw.parameters['CONTROL']['restart_mode'] = 'from_scratch' inputs.pw.parameters['CONTROL']['calculation'] = 'nscf' inputs.pw.parameters['SYSTEM']['nosym'] = True inputs.pw.parameters['SYSTEM']['noinv'] = True inputs.pw.parameters['ELECTRONS']['diagonalization'] = 'cg' inputs.pw.parameters['ELECTRONS']['diago_full_acc'] = True if self.inputs.only_valence: inputs.pw.parameters['SYSTEM']['occupations'] = 'fixed' inputs.pw.parameters['SYSTEM'].pop( 'smearing', None) # pop None to avoid KeyError inputs.pw.parameters['SYSTEM'].pop( 'degauss', None) # pop None to avoid KeyError # inputs.pw.pseudos is an AttributeDict, but calcfunction only accepts # orm.Data, so we unpack it to pass in orm.UpfData inputs.pw.parameters = update_nscf_num_bands( orm.Dict(dict=inputs.pw.parameters), self.ctx.workchain_scf.outputs.output_parameters, self.ctx.current_structure, self.inputs.only_valence, **inputs.pw.pseudos) self.report('nscf number of bands set as ' + str(inputs.pw.parameters['SYSTEM']['nbnd'])) # check kmesh try: inputs.kpoints except AttributeError: # then kpoints_distance must exists, since this is ensured by inputs check of this workchain from aiida_quantumespresso.workflows.functions.create_kpoints_from_distance import create_kpoints_from_distance force_parity = inputs.get('kpoints_force_parity', orm.Bool(False)) kmesh = create_kpoints_from_distance(self.ctx.current_structure, inputs.kpoints_distance, force_parity) #kpoints_data = orm.KpointsData() # kpoints_data.set_cell_from_structure(self.ctx.current_structure) # kmesh = kpoints_data.set_kpoints_mesh_from_density(inputs.kpoints_distance.value) else: try: inputs.kpoints.get_kpoints_mesh() except AttributeError: self.report("nscf only support `mesh' type KpointsData") return self.exit_codes.ERROR_SUB_PROCESS_FAILED_NSCF else: kmesh = inputs.kpoints # convert kmesh to explicit list, since auto generated kpoints # maybe different between QE & Wannier90. Here we explicitly # generate a list of kpoint to avoid discrepencies between # QE's & Wannier90's automatically generated kpoints. self.ctx.nscf_kmesh = kmesh # store it since it will be used by w90 inputs.kpoints = convert_kpoints_mesh_to_list(kmesh) inputs = prepare_process_inputs(PwBaseWorkChain, inputs) running = self.submit(PwBaseWorkChain, **inputs) self.report( 'nscf step - launching PwBaseWorkChain<{}> in {} mode'.format( running.pk, 'nscf')) return ToContext(workchain_nscf=running)