def test_get_inputs_fleur_interface(): from aiida_fleur.tools.common_fleur_wf import get_inputs_fleur code = 'code' fleurinp = 'fleurinp' remote = 'remote' options = {} label = 'test' description = 'test des' inputs = { 'code': code, 'fleurinp': fleurinp, 'remote': remote, 'options': options, 'label': label, 'description': description } returns = { '_description': 'test des', '_label': 'test', '_options': {}, '_store_provenance': True, 'code': 'code', 'dynamic': None, 'fleurinpdata': 'fleurinp', 'parent_folder': 'remote', 'settings': None } assert get_inputs_fleur(**inputs) == returns
def force_wo_scf(self): """ Submit FLEUR force theorem calculation using input remote """ self.report('INFO: run Force theorem calculations') status = self.change_fleurinp() if status: return status fleurin = self.ctx.fleurinp # Do not copy mixing_history* files from the parent settings = {'remove_from_remotecopy_list': ['mixing_history*']} # Retrieve remote folder from the inputs remote = self.inputs.remote label = 'Force_theorem_calculation' description = 'This is a force theorem calculation for all SQA' code = self.inputs.fleur options = self.ctx.options.copy() inputs_builder = get_inputs_fleur( code, remote, fleurin, options, label, description, settings, add_comp_para=self.ctx.wf_dict['add_comp_para']) future = self.submit(FleurBaseWorkChain, **inputs_builder) return ToContext(f_t=future)
def banddos_wo_scf(self): """ This method submits the BandDOS calculation without a previous SCF calculation """ self.report('INFO: run BandDOS calculation') status = self.change_fleurinp() if status: return status fleurin = self.ctx.fleurinp_banddos # Do not copy mixing_history* files from the parent settings = {'remove_from_remotecopy_list': ['mixing_history*']} # Retrieve remote folder from the inputs remote = self.inputs.remote label = 'bansddos_calculation' description = 'Bandstructure or DOS is calculated for the given structure' code = self.inputs.fleur options = self.ctx.options.copy() inputs_builder = get_inputs_fleur( code, remote, fleurin, options, label, description, settings, add_comp_para=self.ctx.wf_dict['add_comp_para']) future = self.submit(FleurBaseWorkChain, **inputs_builder) return ToContext(banddos_calc=future)
def run_fleur(self): """ run a FLEUR calculation """ self.report('INFO: run FLEUR') status = self.change_fleurinp() if status: return status fleurin = self.ctx.fleurinp if 'settings' in self.inputs: settings = self.inputs.settings else: settings = None if self.ctx['last_base_wc']: # will this fail if fleur before failed? try needed? remote = self.ctx['last_base_wc'].outputs.remote_folder elif 'remote_data' in self.inputs: remote = self.inputs.remote_data else: remote = None label = ' ' description = ' ' if self.ctx.formula: label = 'scf: fleur run {}'.format(self.ctx.loop_count + 1) description = '{} fleur run {} on {}'.format( self.ctx.description_wf, self.ctx.loop_count + 1, self.ctx.formula) else: label = 'scf: fleur run {}'.format(self.ctx.loop_count + 1) description = '{} fleur run {}, fleurinp given'.format( self.ctx.description_wf, self.ctx.loop_count + 1) code = self.inputs.fleur options = self.ctx.options.copy() inputs_builder = get_inputs_fleur( code, remote, fleurin, options, label, description, settings, add_comp_para=self.ctx.wf_dict['add_comp_para']) future = self.submit(FleurBaseWorkChain, **inputs_builder) self.ctx.loop_count = self.ctx.loop_count + 1 self.report('INFO: run FLEUR number: {}'.format(self.ctx.loop_count)) self.ctx.calcs.append(future) return ToContext(last_base_wc=future)
def run_fleur(self): """ run a FLEUR calculation """ fleurin = self.ctx.fleurinp1 remote = self.inputs.remote_data code = self.inputs.fleur options = self.ctx.options inputs = get_inputs_fleur(code, remote, fleurin, options, add_comp_para=self.ctx.wf_dict['add_comp_para']) future = submit(FleurCalculation, **inputs) return ToContext(last_calc=future) # calcs.append(future),
def run_fleur(self): """ run a FLEUR calculation """ fleurin = self.ctx.fleurinp1 remote = self.inputs.remote code = self.inputs.fleur options = {"max_wallclock_seconds": self.ctx.walltime_sec, "resources": self.ctx.resources, "queue_name" : self.ctx.queue} inputs = get_inputs_fleur(code, remote, fleurin, options, serial=self.ctx.serial) future = submit(FleurProcess, **inputs) return ToContext(last_calc=future) #calcs.append(future),
def run_fleur(self): """ run a FLEUR calculation """ self.report('INFO: run FLEUR') # inputs = self.get_inputs_scf() fleurin = self.ctx.fleurinp_banddos remote = self.inputs.remote code = self.inputs.fleur options = self.ctx.options.copy() label = 'bansddos_calculation' description = 'Bandstructure or DOS is calculated for the given structure' inputs = get_inputs_fleur(code, remote, fleurin, options, label, description, serial=self.ctx.serial) future = self.submit(FleurBaseWorkChain, **inputs) self.ctx.calcs.append(future) return ToContext(last_calc=future)
def run_fleur(self): """ run a FLEUR calculation """ # check if calculation before is in FINISHED (not failed) #check if inpgen was run before. self.change_fleurinp() fleurin = self.ctx.fleurinp ''' if 'settings' in self.inputs: settings = self.input.settings else: settings = ParameterData(dict={'files_to_retrieve' : [], 'files_not_to_retrieve': [], 'files_copy_remotely': [], 'files_not_copy_remotely': [], 'commandline_options': ["-wtime", "{}".format(self.ctx.walltime_sec)], 'blaha' : ['bla']}) ''' if self.ctx['last_calc']: remote = self.ctx['last_calc'].out.remote_folder elif 'remote_data' in self.inputs: remote = self.inputs.remote_data code = self.inputs.fleur options = { "max_wallclock_seconds": self.ctx.walltime_sec, "resources": self.ctx.resources, "queue_name": self.ctx.queue } #inputs = get_inputs_fleur(code, remote, fleurin, options, settings=settings, serial=self.ctx.serial) inputs = get_inputs_fleur(code, remote, fleurin, options, serial=self.ctx.serial) #print inputs future = submit(FleurProcess, **inputs) self.ctx.loop_count = self.ctx.loop_count + 1 print 'run FLEUR number: {}'.format(self.ctx.loop_count) self.ctx.calcs.append(future) return ToContext(last_calc=future) #calcs.append(future),
def force_after_scf(self): """ Calculate energy of a system for given SQAs using the force theorem. Converged reference is stored in self.ctx['xyz']. """ calc = self.ctx.reference if not calc.is_finished_ok: message = ('The reference SCF calculation was not successful.') self.control_end_wc(message) return self.exit_codes.ERROR_REFERENCE_CALCULATION_FAILED try: outpara_node = calc.outputs.output_scf_wc_para except NotExistent: message = ( 'The reference SCF calculation failed, no scf output node.') self.control_end_wc(message) return self.exit_codes.ERROR_REFERENCE_CALCULATION_FAILED outpara = outpara_node.get_dict() t_e = outpara.get('total_energy', 'failed') if not isinstance(t_e, float): message = ( 'Did not manage to extract float total energy from the reference SCF calculation.' ) self.control_end_wc(message) return self.exit_codes.ERROR_REFERENCE_CALCULATION_FAILED self.report('INFO: run Force theorem calculations') status = self.change_fleurinp() if status: return status fleurin = self.ctx.fleurinp # Do not copy mixing_history* files from the parent settings = {'remove_from_remotecopy_list': ['mixing_history*']} # Retrieve remote folder of the reference calculation pk_last = 0 scf_ref_node = load_node(calc.pk) for i in scf_ref_node.called: if i.node_type == 'process.workflow.workchain.WorkChainNode.': if i.process_class is FleurBaseWorkChain: if pk_last < i.pk: pk_last = i.pk try: remote = load_node(pk_last).outputs.remote_folder except AttributeError: message = ( 'Found no remote folder of the reference scf calculation.') self.control_end_wc(message) return self.exit_codes.ERROR_REFERENCE_CALCULATION_NOREMOTE label = 'MAE_force_theorem' description = 'This is the force theorem calculation for MAE.' code = self.inputs.fleur options = self.ctx.options.copy() inputs_builder = get_inputs_fleur( code, remote, fleurin, options, label, description, settings, add_comp_para=self.ctx.wf_dict['add_comp_para']) future = self.submit(FleurBaseWorkChain, **inputs_builder) return ToContext(f_t=future)
def force_after_scf(self): ''' This routine uses the force theorem to calculate energies dispersion of spin spirals. The force theorem calculations implemented into the FLEUR code. Hence a single iteration FLEUR input file having <forceTheorem> tag has to be created and submitted. ''' calc = self.ctx.reference if not calc.is_finished_ok: message = ('The reference SCF calculation was not successful.') self.control_end_wc(message) return self.exit_codes.ERROR_REFERENCE_CALCULATION_FAILED try: outpara_node = calc.outputs.output_scf_wc_para except NotExistent: message = ('The reference SCF calculation failed, no scf output node.') self.control_end_wc(message) return self.exit_codes.ERROR_REFERENCE_CALCULATION_FAILED outpara = outpara_node.get_dict() if 'total_energy' not in outpara: message = ('Did not manage to extract float total energy from the reference SCF calculation.') self.control_end_wc(message) return self.exit_codes.ERROR_REFERENCE_CALCULATION_FAILED self.report('INFO: run Force theorem calculations') status = self.change_fleurinp() if status: return status fleurin = self.ctx.fleurinp # Do not copy mixing_history* files from the parent settings = {'remove_from_remotecopy_list': ['mixing_history*']} # Retrieve remote folder of the reference calculation pk_last = 0 scf_ref_node = load_node(calc.pk) for i in scf_ref_node.called: if i.node_type == 'process.workflow.workchain.WorkChainNode.': if i.process_class is FleurBaseWorkChain: if pk_last < i.pk: pk_last = i.pk try: remote = load_node(pk_last).outputs.remote_folder except AttributeError: message = ('Found no remote folder of the reference scf calculation.') self.control_end_wc(message) return self.exit_codes.ERROR_REFERENCE_CALCULATION_NOREMOTE label = 'Force_theorem_calculation' description = 'This is a force theorem calculation for all SQA' code = self.inputs.fleur options = self.ctx.options.copy() inputs_builder = get_inputs_fleur(code, remote, fleurin, options, label, description, settings, serial=self.ctx.wf_dict['serial'], only_even_MPI=self.ctx.wf_dict['only_even_MPI']) future = self.submit(FleurBaseWorkChain, **inputs_builder) return ToContext(f_t=future)
def get_inputs_fixed_configurations(self, index, config): """ Sets up the input for the fixed density matrix calculation. """ remote_data = None if self.ctx.scf_no_ldau_needed: try: fleurinp = self.ctx.scf_no_ldau.outputs.fleurinp remote_data = load_node( self.ctx.scf_no_ldau.outputs.output_scf_wc_para['last_calc_uuid']).outputs.remote_folder except NotExistent: error = 'Fleurinp generated in the SCF calculation is not found.' self.control_end_wc(error) return {}, self.exit_codes.ERROR_SCF_NOLDAU_FAILED else: remote_data = self.inputs.remote if 'fleurinp' not in self.inputs: fleurinp = get_fleurinp_from_remote_data(remote_data, store=True) self.report(f'INFO: generated FleurinpData from {fleurinp.files}') else: fleurinp = self.inputs.fleurinp inputs = self.inputs label = f'Fixed_{index}' description = f'LDA+U with fixed nmmpmat for config {index}' if 'settings' not in inputs: settings = {} else: settings = inputs.settings.get_dict() if 'remove_from_remotecopy_list' not in settings: settings['remove_from_remotecopy_list'] = [] settings['remove_from_remotecopy_list'].append('mixing_history*') self.report(f'INFO: create fleurinp for config {index}') fm = FleurinpModifier(fleurinp) fm.set_inpchanges({'itmax': self.ctx.wf_dict['iterations_fixed'], 'l_linMix': True, 'mixParam': 0.0}) for atom_species, ldau_dict in self.ctx.wf_dict['ldau_dict'].items(): fm.set_species(species_name=atom_species, attributedict={'ldaU': ldau_dict}) for config_index, config_species in config.items(): orbital = config_index.split('-')[-1] atom_species = '-'.join(config_index.split('-')[:-1]) for spin, config_spin in enumerate(config_species): if self.ctx.wf_dict['use_orbital_occupation']: fm.set_nmmpmat(species_name=atom_species, orbital=int(orbital), spin=spin + 1, orbital_occupations=config_spin) else: fm.set_nmmpmat(species_name=atom_species, orbital=int(orbital), spin=spin + 1, state_occupations=config_spin) try: fm.show(display=False, validate=True) except etree.DocumentInvalid: error = ('ERROR: input, inp.xml changes did not validate') self.control_end_wc(error) return self.exit_codes.ERROR_INVALID_INPUT_FILE except ValueError as exc: error = ('ERROR: input, inp.xml changes could not be applied.' f'The following error was raised {exc}') self.control_end_wc(error) return self.exit_codes.ERROR_CHANGING_FLEURINPUT_FAILED fleurinp_fixed = fm.freeze() input_fixed = get_inputs_fleur(inputs.fleur, remote_data, fleurinp_fixed, self.ctx.options, label, description, settings=settings) return input_fixed, None
def test_get_inputs_fleur(): ''' Tests if get_inputs_fleur assembles inputs correctly. Note it is the work of FleurCalculation to check if input types are correct i.e. 'code' is a Fleur code etc. ''' from aiida_fleur.tools.common_fleur_wf import get_inputs_fleur from aiida.orm import Dict, Bool inputs = { 'code': 'code', 'remote': 'remote', 'fleurinp': 'fleurinp', 'options': { 'custom_scheduler_commands': 'test_command' }, 'label': 'label', 'description': 'description', 'settings': { 'test': 1 }, 'serial': False, 'only_even_MPI': True } results = get_inputs_fleur(**inputs) out_options = results['options'].get_dict() out_settings = results['settings'].get_dict() assert results['code'] == 'code' assert results['fleurinpdata'] == 'fleurinp' assert results['parent_folder'] == 'remote' assert results['description'] == 'description' assert results['label'] == 'label' assert results['only_even_MPI'] == Bool(True) assert out_options == { 'custom_scheduler_commands': 'test_command', 'withmpi': True } assert out_settings == {'test': 1} inputs = { 'code': 'code', 'remote': 'remote', 'fleurinp': 'fleurinp', 'options': { 'custom_scheduler_commands': 'test_command' }, 'serial': True } results = get_inputs_fleur(**inputs) out_options = results['options'].get_dict() assert results['description'] == '' assert results['label'] == '' assert out_options == { 'custom_scheduler_commands': 'test_command', 'withmpi': False, 'resources': { 'num_machines': 1, 'num_mpiprocs_per_machine': 1 } }
def banddos_after_scf(self): """ This method submits the BandDOS calculation after the initial SCF calculation """ calc = self.ctx.scf if not calc.is_finished_ok: message = ('The SCF calculation was not successful.') self.control_end_wc(message) return self.exit_codes.ERROR_SCF_CALCULATION_FAILED try: outpara_node = calc.outputs.output_scf_wc_para except NotExistent: message = ('The SCF calculation failed, no scf output node.') self.control_end_wc(message) return self.exit_codes.ERROR_SCF_CALCULATION_FAILED outpara = outpara_node.get_dict() if 'total_energy' not in outpara: message = ( 'Did not manage to extract float total energy from the SCF calculation.' ) self.control_end_wc(message) return self.exit_codes.ERROR_SCF_CALCULATION_FAILED self.report('INFO: run BandDOS calculation') status = self.change_fleurinp() if status: return status fleurin = self.ctx.fleurinp_banddos # Do not copy mixing_history* files from the parent settings = {'remove_from_remotecopy_list': ['mixing_history*']} # Retrieve remote folder of the reference calculation pk_last = 0 scf_ref_node = load_node(calc.pk) for i in scf_ref_node.called: if i.node_type == 'process.workflow.workchain.WorkChainNode.': if i.process_class is FleurBaseWorkChain: if pk_last < i.pk: pk_last = i.pk try: remote = load_node(pk_last).outputs.remote_folder except AttributeError: message = ( 'Found no remote folder of the reference scf calculation.') self.control_end_wc(message) return self.exit_codes.ERROR_SCF_CALCULATION_NOREMOTE label = 'bansddos_calculation' description = 'Bandstructure or DOS is calculated for the given structure' code = self.inputs.fleur options = self.ctx.options.copy() inputs_builder = get_inputs_fleur( code, remote, fleurin, options, label, description, settings, add_comp_para=self.ctx.wf_dict['add_comp_para']) future = self.submit(FleurBaseWorkChain, **inputs_builder) return ToContext(banddos_calc=future)
remote = load_node(2357) fleurinp = load_node(2351) options = { "max_wallclock_seconds": 360, "resources": {"num_machines": 1}, "custom_scheduler_commands": 'bla', "queue_name": 'th1', #"computer": Computer, "withmpi": True, #"mpirun_extra_params": Any(list, tuple), "import_sys_environment": False, "environment_variables": {}, "priority": 'High', "max_memory_kb": 62, "prepend_text": 'this is a test', "append_text": 'this was a test'} inp = get_inputs_fleur(codeNode, remote, fleurinp, options, serial=False) print inp inputs = {} options2 = {"max_wallclock_seconds": 360, "resources": {"num_machines": 1}} inputs = get_inputs_fleur(codeNode, remote, fleurinp, options2, serial=True) #print inputs #future = submit(FleurProcess, **inputs) print 'run Fleur' # test get inputs_fleur inputs = {} structure =load_node(2469) inpgencode = is_code(2)
def run_fleur(self): """ run a FLEUR calculation """ self.change_fleurinp() fleurin = self.ctx.fleurinp ''' if 'settings' in self.inputs: settings = self.input.settings else: settings = ParameterData(dict={'files_to_retrieve' : [], 'files_not_to_retrieve': [], 'files_copy_remotely': [], 'files_not_copy_remotely': [], 'commandline_options': ["-wtime", "{}".format(self.ctx.walltime_sec)], 'blaha' : ['bla']}) ''' if self.ctx['last_calc']: # will this fail if fleur before failed? try needed? remote = self.ctx['last_calc'].out.remote_folder elif 'remote_data' in self.inputs: remote = self.inputs.remote_data else: remote = None label = ' ' description = ' ' if self.ctx.formula: label = 'scf: fleur run {}'.format(self.ctx.loop_count + 1) description = '{} fleur run {} on {}'.format( self.ctx.description_wf, self.ctx.loop_count + 1, self.ctx.formula) else: label = 'scf: fleur run {}'.format(self.ctx.loop_count + 1) description = '{} fleur run {}, fleurinp given'.format( self.ctx.description_wf, self.ctx.loop_count + 1) code = self.inputs.fleur options = { "max_wallclock_seconds": self.ctx.walltime_sec, "resources": self.ctx.resources, "queue_name": self.ctx.queue } #, if self.ctx.custom_scheduler_commands: options[ "custom_scheduler_commands"] = self.ctx.custom_scheduler_commands inputs = get_inputs_fleur(code, remote, fleurin, options, label, description, serial=self.ctx.serial) future = submit(FleurProcess, **inputs) self.ctx.loop_count = self.ctx.loop_count + 1 self.report('INFO: run FLEUR number: {}'.format(self.ctx.loop_count)) self.ctx.calcs.append(future) return ToContext(last_calc=future)