def start(self): """ check parameters, what condictions? complete? check input nodes """ self.report('started eos workflow version {}'.format(self._workflowversion)) self.report("Workchain node identifiers: {}".format(ProcessRegistry().current_calc_node)) #print('started eos workflow version {}'.format(self._workflowversion)) #print("Workchain node identifiers: {}".format(ProcessRegistry().current_calc_node)) ### input check ### ? or done automaticly, how optional? self.ctx.last_calc2 = None self.ctx.calcs = [] self.ctx.calcs_future = [] self.ctx.structures = [] self.ctx.temp_calc = None self.ctx.structurs_uuids = [] self.ctx.scalelist = [] self.ctx.volume = [] self.ctx.volume_peratom = [] self.ctx.org_volume = -1# avoid div 0 self.ctx.labels = [] self.ctx.successful = True#False # TODO get all succesfull from convergence, if all True this wf_dict = self.inputs.wf_parameters.get_dict() # set values, or defaults, default: always converge charge density, # crit < 0.00002, max 4 fleur runs self.ctx.points = wf_dict.get('points', 9) self.ctx.step = wf_dict.get('step', 0.002) self.ctx.guess = wf_dict.get('guess', 1.00) self.ctx.serial = wf_dict.get('serial', False)#True self.ctx.custom_scheduler_commands = wf_dict.get('custom_scheduler_commands', '') self.ctx.max_number_runs = wf_dict.get('fleur_runmax', 4) inputs = self.inputs if 'inpgen' in inputs: try: test_and_get_codenode(inputs.inpgen, 'fleur.inpgen', use_exceptions=True) except ValueError: error = ("The code you provided for inpgen of FLEUR does not " "use the plugin fleur.inpgen") #self.control_end_wc(error) print(error) self.abort(error) if 'fleur' in inputs: try: test_and_get_codenode(inputs.fleur, 'fleur.fleur', use_exceptions=True) except ValueError: error = ("The code you provided for FLEUR does not " "use the plugin fleur.fleur") #self.control_end_wc(error) #print(error) self.abort(error)
def start(self): """ check parameters, what condictions? complete? check input nodes """ self.report( 'started fleur_optimize_parameter workflow version {}'.format( self._workflowversion)) self.report("Workchain node identifiers: {}".format( ProcessRegistry().current_calc_node)) ### input check ### # initialize contexts self.ctx.successful = True # Check on inputnodes inputs = self.inputs # wf_parameters: wf_dict = inputs.wf_parameters.get_dict() # set values, or DEFAULTS self.ctx.serial = wf_dict.get('serial', False) self.ctx.custom_scheduler_commands = wf_dict.get( 'custom_scheduler_commands', '') self.ctx.max_number_runs = wf_dict.get('fleur_runmax', 4) # codes if 'inpgen' in inputs: try: test_and_get_codenode(inputs.inpgen, 'fleur.inpgen', use_exceptions=True) except ValueError: error = ("The code you provided for inpgen of FLEUR does not " "use the plugin fleur.inpgen") self.control_end_wc(error) self.abort(error) if 'fleur' in inputs: try: test_and_get_codenode(inputs.fleur, 'fleur.fleur', use_exceptions=True) except ValueError: error = ("The code you provided for FLEUR does not " "use the plugin fleur.fleur") self.control_end_wc(error) self.abort(error)
def test_test_and_get_codenode_inpgen(): from aiida_fleur.tools.common_fleur_wf import test_and_get_codenode from aiida.orm import Code from aiida.common.exceptions import NotExistent # install code setup code code = Code(input_plugin_name='fleur.inpgen') code.label = 'inpgen' #code = Code.get_from_string('inpgen@localhost') expected = 'fleur.inpgen' nonexpected = 'fleur.fleur' assert isinstance(test_and_get_codenode(code, expected), Code) with pytest.raises(ValueError) as msg: test_and_get_codenode(code, nonexpected, use_exceptions=True) assert 'Code not valid' in str(msg)
def start(self): ''' check parameters, what condictions? complete? check input nodes ''' ### input check ### ? or done automaticly, how optional? # check if fleuinp corresponds to fleur_calc print('started dos workflow version {}'.format(self._workflowversion)) print("Workchain node identifiers: {}" "".format(ProcessRegistry().current_calc_node)) self.ctx.fleurinp1 = "" self.ctx.last_calc = None self.ctx.successful = False self.ctx.warnings = [] wf_dict = self.inputs.wf_parameters.get_dict() # if MPI in code name, execute parallel self.ctx.serial = wf_dict.get('serial', False) # set values, or defaults self.ctx.max_number_runs = wf_dict.get('fleur_runmax', 4) self.ctx.resources = wf_dict.get('resources', {"num_machines": 1}) self.ctx.walltime_sec = wf_dict.get('walltime_sec', 10 * 60) self.ctx.queue = wf_dict.get('queue_name', None) inputs = self.inputs if 'fleur' in inputs: try: test_and_get_codenode(inputs.fleur, 'fleur.fleur', use_exceptions=True) except ValueError: error = ("The code you provided for FLEUR does not " "use the plugin fleur.fleur") #self.control_end_wc(error) print(error) self.abort()
def start(self): ''' check parameters, what condictions? complete? check input nodes ''' # input check ### ? or done automaticly, how optional? # check if fleuinp corresponds to fleur_calc self.report('Started dos workflow version {}' # "Workchain node identifiers: ")#{}" ''.format(self._workflowversion)) # ProcessRegistry().current_calc_node)) self.ctx.fleurinp1 = '' self.ctx.last_calc = None self.ctx.successful = False self.ctx.warnings = [] wf_dict = self.inputs.wf_parameters.get_dict() # if MPI in code name, execute parallel self.ctx.serial = wf_dict.get('serial', False) # set values, or defaults self.ctx.max_number_runs = wf_dict.get('fleur_runmax', 4) inputs = self.inputs if 'options' in inputs: self.ctx.options = inputs.options.get_dict() if 'remote_data' in inputs: self.ctx.remote = inputs.remote_data if 'fleur' in inputs: try: test_and_get_codenode(inputs.fleur, 'fleur.fleur', use_exceptions=True) except ValueError: error = ('The code you provided for FLEUR does not use the plugin fleur.fleur') # self.control_end_wc(error) self.report(error) return 1
def test_test_and_get_codenode_inpgen(fixture_code): """Tests for test_and_get_code_node function test interface for cases: if code exists and is right, if code is wrong, if code does not exists """ from aiida_fleur.tools.common_fleur_wf import test_and_get_codenode from aiida.orm import Code from aiida.common.exceptions import NotExistent # install code setup code code = fixture_code('fleur.inpgen') code_fleur = fixture_code('fleur.fleur') code_fleur.label = 'fleur_test' code_fleur.store() expected = 'fleur.inpgen' nonexpected = 'fleur.fleur' not_existing = 'fleur.not_existing' assert isinstance(test_and_get_codenode(code, expected), Code) with pytest.raises(ValueError) as msg: test_and_get_codenode(code, nonexpected, use_exceptions=True) assert str( msg.value) == ('Given Code node is not of expected code type.\n' 'Valid labels for a fleur.fleur executable are:\n' '* fleur_test@localhost-test') with pytest.raises(ValueError) as msg: test_and_get_codenode(code, not_existing, use_exceptions=True) assert str(msg.value) == ( 'Code not valid, and no valid codes for fleur.not_existing.\n' 'Configure at least one first using\n' ' verdi code setup')
def start(self): """ Retrieve and initialize paramters of the WorkChain """ self.report('INFO: started Spin Stiffness calculation workflow version {}\n' ''.format(self._workflowversion)) self.ctx.info = [] self.ctx.warnings = [] self.ctx.errors = [] self.ctx.energy_dict = [] # initialize the dictionary using defaults if no wf paramters are given wf_default = copy.deepcopy(self._default_wf_para) if 'wf_parameters' in self.inputs: wf_dict = self.inputs.wf_parameters.get_dict() else: wf_dict = wf_default extra_keys = [] for key in wf_dict.keys(): if key not in wf_default.keys(): extra_keys.append(key) if extra_keys: error = 'ERROR: input wf_parameters for SSDisp contains extra keys: {}'.format(extra_keys) self.report(error) return self.exit_codes.ERROR_INVALID_INPUT_PARAM # extend wf parameters given by user using defaults for key, val in six.iteritems(wf_default): wf_dict[key] = wf_dict.get(key, val) self.ctx.wf_dict = wf_dict if wf_dict['ref_qss'] != wf_dict['q_vectors'][0]: error = ('The first q_vector of the forceTheorem step has to be equal to' 'the q vector of the reference calculation.') self.control_end_wc(error) return self.exit_codes.ERROR_INVALID_INPUT_PARAM # initialize the dictionary using defaults if no options are given defaultoptions = self._default_options if 'options' in self.inputs: options = self.inputs.options.get_dict() else: options = defaultoptions # extend options given by user using defaults for key, val in six.iteritems(defaultoptions): options[key] = options.get(key, val) self.ctx.options = options # Check if user gave valid fleur executable inputs = self.inputs if 'fleur' in inputs: try: test_and_get_codenode(inputs.fleur, 'fleur.fleur', use_exceptions=True) except ValueError: error = 'The code you provided for FLEUR does not use the plugin fleur.fleur' self.control_end_wc(error) return self.exit_codes.ERROR_INVALID_CODE_PROVIDED # Check if user gave an input setup making any sense if inputs.scf: self.ctx.scf_needed = True if 'remote' in inputs: error = 'ERROR: you gave SCF input + remote for the FT' self.control_end_wc(error) return self.exit_codes.ERROR_INVALID_INPUT_CONFIG if 'fleurinp' in inputs: error = 'ERROR: you gave SCF input + fleurinp for the FT' self.control_end_wc(error) return self.exit_codes.ERROR_INVALID_INPUT_CONFIG elif 'remote' not in inputs: error = 'ERROR: you gave neither SCF input nor remote for the FT' self.control_end_wc(error) return self.exit_codes.ERROR_INVALID_INPUT_CONFIG else: self.ctx.scf_needed = False
if args.fleurinp is not None: inputs['fleurinp'] = load_node(args.fleurinp) else: inputs['fleurinp'] = default['fleurinp'] if args.remote_data is not None: inputs['remote_data'] = load_node(args.remote_data) if args.options is not None: inputs['options'] = load_node(args.options) else: inputs['options'] = default['options'] fleur_code = is_code(args.fleur) inputs['fleur'] = test_and_get_codenode(fleur_code, expected_code_type='fleur.fleur') submit_wc = False if args.submit is not None: submit_wc = submit pprint(inputs) print('##################### TEST FleurBandWorkChain #####################') if submit_wc: res = submit(FleurBandWorkChain, **inputs) print( '##################### Submited FleurBandWorkChain #####################' ) print(('Runtime info: {}'.format(res))) print(
options_scf = Dict( dict={ 'resources': { 'num_machines': 1, 'num_mpiprocs_per_machine': 2 }, 'queue_name': '', 'custom_scheduler_commands': '', 'max_wallclock_seconds': 60 * 60 }) #### fleur_code = is_code(args.fleur) fleur_inp = test_and_get_codenode(fleur_code, expected_code_type='fleur.fleur') inpgen_code = is_code(args.inpgen) inpgen_inp = test_and_get_codenode(inpgen_code, expected_code_type='fleur.inpgen') inputs = { 'scf': { 'wf_parameters': wf_para_scf, 'structure': structure, 'calc_parameters': parameters, 'options': options_scf, 'inpgen': inpgen_inp, 'fleur': fleur_inp }, 'wf_parameters': wf_para, 'fleur': fleur_inp,
def start(self): """ check parameters, what condictions? complete? check input nodes """ self.report('started simple eos workflow version {}'.format( self._workflowversion)) self.report("Workchain node identifiers: {}".format( ProcessRegistry().current_calc_node)) ### input check ### # initialize contexts self.ctx.last_calc2 = None self.ctx.calcs = [] self.ctx.calcs_future = [] self.ctx.structures = [] self.ctx.temp_calc = None self.ctx.structurs_uuids = [] self.ctx.scalelist = [] self.ctx.volume = [] self.ctx.volume_peratom = [] self.ctx.org_volume = -1 # avoid div 0 self.ctx.labels = [] self.ctx.successful = True # Check on inputnodes inputs = self.inputs # wf_parameters: wf_dict = inputs.wf_parameters.get_dict() # set values, or DEFAULTS self.ctx.points = wf_dict.get('points', 9) self.ctx.step = wf_dict.get('step', 0.002) self.ctx.guess = wf_dict.get('guess', 1.00) self.ctx.serial = wf_dict.get('serial', False) self.ctx.custom_scheduler_commands = wf_dict.get( 'custom_scheduler_commands', '') self.ctx.max_number_runs = wf_dict.get('fleur_runmax', 4) # codes if 'inpgen' in inputs: try: test_and_get_codenode(inputs.inpgen, 'fleur.inpgen', use_exceptions=True) except ValueError: error = ("The code you provided for inpgen of FLEUR does not " "use the plugin fleur.inpgen") self.control_end_wc(error) self.abort(error) if 'fleur' in inputs: try: test_and_get_codenode(inputs.fleur, 'fleur.fleur', use_exceptions=True) except ValueError: error = ("The code you provided for FLEUR does not " "use the plugin fleur.fleur") self.control_end_wc(error) self.abort(error)
inputs['calc_parameters'] = parameters parameters.store() if args.wf_parameters is not None: inputs['wf_parameters'] = load_node(args.wf_parameters) else: wf_para = Dict(dict={'references': {'W': [structure.uuid, parameters.uuid]}}) inputs['wf_parameters'] = wf_para if args.options is not None: inputs['options'] = load_node(args.options) else: inputs['options'] = default['options'] fleur_code = is_code(args.fleur) inputs['fleur'] = test_and_get_codenode(fleur_code, expected_code_type='fleur.fleur') if args.inpgen is not None: inpgen_code = is_code(args.inpgen) inputs['inpgen'] = test_and_get_codenode(inpgen_code, expected_code_type='fleur.inpgen') submit_wc = False if args.submit is not None: submit_wc = submit pprint(inputs) #builder = fleur_scf_wc.get_builder() print('##################### TEST fleur_initial_cls_wc #####################') if submit_wc:
def start(self): """ check parameters, what conditions? complete? check input nodes """ self.report('Started strain workflow version {}'.format( self._workflowversion)) self.ctx.last_calc2 = None self.ctx.calcs = [] self.ctx.calcs_future = [] self.ctx.structures = [] self.ctx.temp_calc = None self.ctx.structurs_uuids = [] self.ctx.scalelist = [] self.ctx.volume = [] self.ctx.volume_peratom = {} self.ctx.org_volume = -1 # avoid div 0 self.ctx.labels = [] self.ctx.successful = True self.ctx.info = [] self.ctx.warnings = [] self.ctx.errors = [] # TODO get all successful from convergence, if all True this # initialize the dictionary using defaults if no wf parameters are given wf_default = self._wf_default if 'wf_parameters' in self.inputs: wf_dict = self.inputs.wf_parameters.get_dict() else: wf_dict = wf_default # extend wf parameters given by user using defaults for key, val in six.iteritems(wf_default): wf_dict[key] = wf_dict.get(key, val) self.ctx.wf_dict = wf_dict self.ctx.points = wf_dict.get('points', 3) self.ctx.step = wf_dict.get('step', 0.02) self.ctx.guess = wf_dict.get('guess', 1.00) self.ctx.serial = wf_dict.get('serial', False) # True self.ctx.max_number_runs = wf_dict.get('fleur_runmax', 4) # initialize the dictionary using defaults if no options are given defaultoptions = self._default_options if 'options' in self.inputs: options = self.inputs.options.get_dict() else: options = defaultoptions # extend options given by user using defaults for key, val in six.iteritems(defaultoptions): options[key] = options.get(key, val) self.ctx.options = options # Check if user gave valid inpgen and fleur executables inputs = self.inputs if 'inpgen' in inputs: try: test_and_get_codenode(inputs.inpgen, 'fleur.inpgen', use_exceptions=True) except ValueError: error = ( 'The code you provided for inpgen of FLEUR does not use the plugin fleur.inpgen' ) self.control_end_wc(error) return self.exit_codes.ERROR_INVALID_CODE_PROVIDED if 'fleur' in inputs: try: test_and_get_codenode(inputs.fleur, 'fleur.fleur', use_exceptions=True) except ValueError: error = ( 'The code you provided for FLEUR does not use the plugin fleur.fleur' ) self.control_end_wc(error) return self.exit_codes.ERROR_INVALID_CODE_PROVIDED
def validate_input(self): """ # validate input and find out which path (1, or 2) to take # return True means run inpgen if false run fleur directly """ extra_keys = [] for key in self.ctx.wf_dict.keys(): if key not in self._default_wf_para.keys(): extra_keys.append(key) if extra_keys: error = 'ERROR: input wf_parameters for SCF contains extra keys: {}'.format( extra_keys) self.report(error) return self.exit_codes.ERROR_INVALID_INPUT_PARAM inputs = self.inputs if 'fleurinp' in inputs: self.ctx.run_inpgen = False if 'structure' in inputs: error = 'ERROR: structure input is not needed because Fleurinp was given' self.report(error) return self.exit_codes.ERROR_INVALID_INPUT_CONFIG if 'inpgen' in inputs: error = 'ERROR: inpgen code is not needed input because Fleurinp was given' self.report(error) return self.exit_codes.ERROR_INVALID_INPUT_CONFIG if 'calc_parameters' in inputs: error = 'ERROR: calc_parameters input is not needed because Fleurinp was given' self.report(error) return self.exit_codes.ERROR_INVALID_INPUT_CONFIG if 'remote_data' in inputs: warning = ( 'WARNING: Only initial charge density will be copied from the' 'given remote folder because fleurinp is given.') self.report(warning) elif 'structure' in inputs: self.ctx.run_inpgen = True if not 'inpgen' in inputs: error = 'ERROR: StructureData was provided, but no inpgen code was provided' self.report(error) return self.exit_codes.ERROR_INVALID_INPUT_CONFIG if 'remote_data' in inputs: warning = ( 'WARNING: Only initial charge density will be copied from the' 'given remote folder because fleurinp is given.') self.report(warning) elif 'remote_data' in inputs: self.ctx.run_inpgen = False else: error = 'ERROR: No StructureData nor FleurinpData nor RemoteData was provided' return self.exit_codes.ERROR_INVALID_INPUT_CONFIG if 'inpgen' in inputs: try: test_and_get_codenode(inputs.inpgen, 'fleur.inpgen', use_exceptions=True) except ValueError: error = ( 'The code you provided for inpgen of FLEUR does not use the plugin fleur.inpgen' ) return self.exit_codes.ERROR_INVALID_CODE_PROVIDED if 'fleur' in inputs: try: test_and_get_codenode(inputs.fleur, 'fleur.fleur', use_exceptions=True) except ValueError: error = ( 'The code you provided for FLEUR does not use the plugin fleur.fleur' ) return self.exit_codes.ERROR_INVALID_CODE_PROVIDED # check the mode in wf_dict mode = self.ctx.wf_dict.get('mode') if mode not in ['force', 'density', 'energy', 'gw']: error = ( 'ERROR: Wrong mode of convergence' + ": one of 'force', 'density', 'energy' or 'gw' was expected.") return self.exit_codes.ERROR_INVALID_INPUT_PARAM max_iters = self.ctx.wf_dict.get('itmax_per_run') if max_iters <= 1: error = ("ERROR: 'itmax_per_run' should be equal at least 2") return self.exit_codes.ERROR_INVALID_INPUT_PARAM # check format of inpxml_changes fchanges = self.ctx.wf_dict.get('inpxml_changes', []) if fchanges: for change in fchanges: # somehow the tuple type gets destroyed on the way and becomes a list if (not isinstance(change, tuple)) and (not isinstance( change, list)): error = ( 'ERROR: Wrong Input inpxml_changes wrong format of' ': {} should be tuple of 2. I abort'.format(change)) return self.exit_codes.ERROR_INVALID_INPUT_PARAM return
def start(self): """ Retrieve and initialize paramters of the WorkChain """ self.report( 'INFO: started Magnetic Anisotropy Energy calculation workflow version {}\n' ''.format(self._workflowversion)) self.ctx.info = [] self.ctx.warnings = [] self.ctx.errors = [] self.ctx.t_energydict = [] self.ctx.mae_thetas = [] self.ctx.mae_phis = [] self.ctx.fleuroutuuid = None # initialize the dictionary using defaults if no wf paramters are given wf_default = copy.deepcopy(self._default_wf_para) if 'wf_parameters' in self.inputs: wf_dict = self.inputs.wf_parameters.get_dict() else: wf_dict = wf_default extra_keys = [] for key in wf_dict.keys(): if key not in wf_default.keys(): extra_keys.append(key) if extra_keys: error = 'ERROR: input wf_parameters for MAE contains extra keys: {}'.format( extra_keys) self.report(error) return self.exit_codes.ERROR_INVALID_INPUT_PARAM # extend wf parameters given by user using defaults for key, val in six.iteritems(wf_default): wf_dict[key] = wf_dict.get(key, val) self.ctx.wf_dict = wf_dict # switch off SOC on an atom specie for atom_label in self.ctx.wf_dict['soc_off']: self.ctx.wf_dict['inpxml_changes'].append(('set_species_label', { 'at_label': atom_label, 'attributedict': { 'special': { 'socscale': 0.0 } }, 'create': True })) # Check if sqas_theta and sqas_phi have the same length if len(self.ctx.wf_dict.get('sqas_theta')) != len( self.ctx.wf_dict.get('sqas_phi')): error = ( 'Number of sqas_theta has to be equal to the number of sqas_phi' ) self.control_end_wc(error) return self.exit_codes.ERROR_INVALID_INPUT_PARAM # initialize the dictionary using defaults if no options are given defaultoptions = self._default_options if 'options' in self.inputs: options = self.inputs.options.get_dict() else: options = defaultoptions # extend options given by user using defaults for key, val in six.iteritems(defaultoptions): options[key] = options.get(key, val) self.ctx.options = options # Check if user gave valid fleur executable inputs = self.inputs if 'fleur' in inputs: try: test_and_get_codenode(inputs.fleur, 'fleur.fleur', use_exceptions=True) except ValueError: error = ( 'The code you provided for FLEUR does not use the plugin fleur.fleur' ) self.control_end_wc(error) return self.exit_codes.ERROR_INVALID_CODE_PROVIDED # Check if user gave an input setup making any sense if 'scf' in inputs: self.ctx.scf_needed = True if 'remote' in inputs: error = 'ERROR: you gave SCF input + remote for the FT' self.control_end_wc(error) return self.exit_codes.ERROR_INVALID_INPUT_CONFIG if 'fleurinp' in inputs: error = 'ERROR: you gave SCF input + fleurinp for the FT' self.control_end_wc(error) return self.exit_codes.ERROR_INVALID_INPUT_CONFIG elif 'remote' not in inputs: error = 'ERROR: you gave neither SCF input nor remote for the FT' self.control_end_wc(error) return self.exit_codes.ERROR_INVALID_INPUT_CONFIG else: self.ctx.scf_needed = False
def validate_input(self): """ # validate input and find out which path (1, or 2) to take # return True means run inpgen if false run fleur directly """ run_inpgen = True inputs = self.inputs if 'fleurinp' in inputs: run_inpgen = False if 'structure' in inputs: warning = 'WARNING: Ignoring Structure input, because Fleurinp was given' self.ctx.warnings.append(warning) self.report(warning) if 'inpgen' in inputs: warning = 'WARNING: Ignoring inpgen code input, because Fleurinp was given' self.ctx.warnings.append(warning) self.report(warning) if 'calc_parameters' in inputs: warning = 'WARNING: Ignoring parameter input, because Fleurinp was given' self.ctx.warnings.append(warning) self.report(warning) elif 'structure' in inputs: if not 'inpgen' in inputs: error = 'ERROR: StructureData was provided, but no inpgen code was provided' self.ctx.errors.append(error) self.control_end_wc(error) else: error = 'ERROR: No StructureData nor FleurinpData was provided' self.ctx.errors.append(error) self.control_end_wc(error) if 'inpgen' in inputs: try: test_and_get_codenode(inputs.inpgen, 'fleur.inpgen', use_exceptions=True) except ValueError: error = ("The code you provided for inpgen of FLEUR does not " "use the plugin fleur.inpgen") self.control_end_wc(error) if 'fleur' in inputs: try: test_and_get_codenode(inputs.fleur, 'fleur.fleur', use_exceptions=True) except ValueError: error = ("The code you provided for FLEUR does not " "use the plugin fleur.fleur") self.control_end_wc(error) # maybe ckeck here is unessesary... wf_dict = self.inputs.wf_parameters.get_dict() if wf_dict == {}: wf_dict = self._wf_default # check format of inpxml_changes fchanges = wf_dict.get('inpxml_changes', []) if fchanges: for change in fchanges: # somehow the tuple type gets destroyed on the way and becomes a list if (not isinstance(change, tuple)) and (not isinstance( change, list)): error = ( 'ERROR: Wrong Input inpxml_changes wrong format of' ': {} should be tuple of 2. I abort'.format(change)) self.control_end_wc(error) return run_inpgen
def start(self): ''' check parameters, what condictions? complete? check input nodes ''' ### input check ### ? or done automaticly, how optional? # check if fleuinp corresponds to fleur_calc self.report('started bandsdos workflow version {}'.format( self._workflowversion)) #print("Workchain node identifiers: ")#'{}' #"".format(ProcessRegistry().current_calc_node)) self.ctx.scf_needed = False self.ctx.banddos_calc = None self.ctx.successful = False self.ctx.info = [] self.ctx.warnings = [] self.ctx.errors = [] inputs = self.inputs wf_default = copy.deepcopy(self._default_wf_para) if 'wf_parameters' in inputs: wf_dict = inputs.wf_parameters.get_dict() else: wf_dict = wf_default for key, val in wf_default.items(): wf_dict[key] = wf_dict.get(key, val) self.ctx.wf_dict = wf_dict defaultoptions = self._default_options if 'options' in inputs: options = inputs.options.get_dict() else: options = defaultoptions # extend options given by user using defaults for key, val in defaultoptions.items(): options[key] = options.get(key, val) self.ctx.options = options if 'fleur' in inputs: try: test_and_get_codenode(inputs.fleur, 'fleur.fleur', use_exceptions=True) except ValueError: error = 'The code you provided for FLEUR does not use the plugin fleur.fleur' self.control_end_wc(error) return self.exit_codes.ERROR_INVALID_CODE_PROVIDED if 'scf' in inputs: self.ctx.scf_needed = True if 'remote' in inputs: error = 'ERROR: you gave SCF input + remote for the BandDOS calculation' self.control_end_wc(error) return self.exit_codes.ERROR_INVALID_INPUT_CONFIG if 'fleurinp' in inputs: error = 'ERROR: you gave SCF input + fleurinp for the BandDOS calculation' self.control_end_wc(error) return self.exit_codes.ERROR_INVALID_INPUT_CONFIG elif 'remote' not in inputs: error = 'ERROR: you gave neither SCF input nor remote' self.control_end_wc(error) return self.exit_codes.ERROR_INVALID_INPUT_CONFIG else: self.ctx.scf_needed = False if wf_dict['mode'] == 'dos' and wf_dict['kpath'] not in ('auto', 'skip'): error = 'ERROR: you specified the DOS mode but provided a non default kpath argument' self.control_end_wc(error) return self.exit_codes.ERROR_INVALID_INPUT_PARAM if wf_dict['kpoints_number'] is not None and wf_dict[ 'kpoints_number'] is not None: error = 'ERROR: Only provide either the distance or number for the kpoints' self.control_end_wc(error) return self.exit_codes.ERROR_INVALID_INPUT_PARAM
def validate_input(self): """ validate input """ extra_keys = [] for key in self.ctx.wf_dict.keys(): if key not in self._wf_default.keys(): extra_keys.append(key) if extra_keys: error = 'ERROR: input wf_parameters for Orbcontrol contains extra keys: {}'.format(extra_keys) self.report(error) return self.exit_codes.ERROR_INVALID_INPUT_PARAM ldau_dict = self.ctx.wf_dict.get('ldau_dict') ldau_keys_required = ['l', 'U', 'J', 'l_amf'] if ldau_dict is not None: missing = [] for species, current in ldau_dict.items(): for key in ldau_keys_required: if key not in current: missing.append(key) if missing: error = 'ERROR: Missing input: The following required keys are missing from ldau_dict' \ f' for species {species}: {missing}' self.report(error) return self.exit_codes.ERROR_INVALID_INPUT_PARAM else: error = 'ERROR: Missing input: ldau_dict was not speciified' self.report(error) return self.exit_codes.ERROR_INVALID_INPUT_PARAM max_iters = self.ctx.wf_dict.get('iterations_fixed') if max_iters <= 1: error = "ERROR: 'iterations_fixed' should be equal at least 2" self.report(error) return self.exit_codes.ERROR_INVALID_INPUT_PARAM occupations_dict = self.ctx.wf_dict.get('fixed_occupations') configurations_dict = self.ctx.wf_dict.get('fixed_configurations') #TODO:check occupations or configurations if occupations_dict is not None: if configurations_dict is not None: error = 'ERROR: Invalid input: Only provide one of fixed_occupations and fixed_configurations' self.report(error) return self.exit_codes.ERROR_INVALID_INPUT_PARAM for species, occ_species in occupations_dict.items(): for orbital, occ in occ_species.items(): if species not in ldau_dict: error = f'ERROR: Invalid input: {species} defined in fixed_occupations but not in ldau_dict' self.report(error) return self.exit_codes.ERROR_INVALID_INPUT_PARAM else: missing = False if isinstance(ldau_dict[species], dict): if int(orbital) != ldau_dict[species]['l']: missing = True else: for index, current_dict in enumerate(ldau_dict[species]): if int(orbital) == current_dict['l']: break if index == len(ldau_dict) - 1: missing = True if missing: error = f'ERROR: Invalid input: Orbital {orbital} is given in fixed_occupations for {species}, ' \ ' but it is not defined in ldau_dict' self.report(error) return self.exit_codes.ERROR_INVALID_INPUT_PARAM if not isinstance(occ, list): error = f'ERROR: Invalid input: {species} defined in fixed_occupations invalid type' self.report(error) return self.exit_codes.ERROR_INVALID_INPUT_PARAM else: if configurations_dict is not None: for species, occ_species in occupations_dict.items(): for orbital, occ in occ_species.items(): if species not in ldau_dict: error = f'ERROR: Invalid input: {species} defined in fixed_configurations but not in ldau_dict' self.report(error) return self.exit_codes.ERROR_INVALID_INPUT_PARAM else: missing = False if isinstance(ldau_dict[species], dict): if int(orbital) != ldau_dict[species]['l']: missing = True else: for index, current_dict in enumerate(ldau_dict[species]): if int(orbital) == current_dict['l']: break if index == len(ldau_dict) - 1: missing = True if missing: error = f'ERROR: Invalid input: Orbital {orbital} is given in fixed_configurations for {species}, ' \ ' but it is not defined in ldau_dict' self.report(error) return self.exit_codes.ERROR_INVALID_INPUT_PARAM if not isinstance(occ, list): error = f'ERROR: Invalid input: {species} defined in fixed_configurations invalid type' self.report(error) return self.exit_codes.ERROR_INVALID_INPUT_PARAM else: error = 'ERROR: Missing input: Provide one of fixed_occupations or fixed_configurations' self.report(error) return self.exit_codes.ERROR_INVALID_INPUT_PARAM inputs = self.inputs if 'fleur' in inputs: try: test_and_get_codenode(inputs.fleur, 'fleur.fleur', use_exceptions=True) except ValueError: error = ('The code you provided for FLEUR does not use the plugin fleur.fleur') return self.exit_codes.ERROR_INVALID_CODE_PROVIDED fleurinp = None remote = None if 'scf_no_ldau' in inputs: input_scf = AttributeDict(self.exposed_inputs(FleurScfWorkChain, namespace='scf_no_ldau')) self.ctx.scf_no_ldau_needed = True if 'fleurinp' in input_scf: fleurinp = input_scf.fleurinp if 'remote_data' in input_scf: remote = input_scf.remote_data if 'remote' in inputs: error = 'ERROR: you gave SCF input + remote for the Orbcontrol calculation' self.control_end_wc(error) return self.exit_codes.ERROR_INVALID_INPUT_CONFIG if 'fleurinp' in inputs: error = 'ERROR: you gave SCF input + fleurinp for the Orbcontrol calculation' self.control_end_wc(error) return self.exit_codes.ERROR_INVALID_INPUT_CONFIG elif 'remote' not in inputs: error = 'ERROR: you gave neither SCF input nor remote' self.control_end_wc(error) return self.exit_codes.ERROR_INVALID_INPUT_CONFIG else: remote = inputs.remote if 'fleurinp' in inputs: fleurinp = inputs.fleurinp if fleurinp is not None: modes = fleurinp.get_fleur_modes() if modes['ldau']: error = f"ERROR: Wrong input: fleurinp {'in scf_no_ldau' if 'scf_no_ldau' in inputs else ''} already contains LDA+U" self.report(error) return self.exit_codes.ERROR_INVALID_INPUT_PARAM if remote is not None: parent_calcs = remote.get_incoming(node_class=CalcJob).all() parent_calc = parent_calcs[0].node retrieved_filenames = [x.name for x in parent_calc.outputs.retrieved.list_objects()] if self._NMMPMAT_FILE_NAME in retrieved_filenames or \ self._NMMPMAT_HDF5_FILE_NAME in retrieved_filenames: error = f"ERROR: Wrong input: remote_data {'in scf_no_ldau' if 'scf_no_ldau' in inputs else ''} already contains LDA+U" self.report(error) return self.exit_codes.ERROR_INVALID_INPUT_PARAM