def prepare_for_submission(self, tempfolder): """Create the input files from the input nodes passed to this instance of the `CalcJob`. :param tempfolder: an `aiida.common.folders.Folder` to temporarily write files on disk :return: `aiida.common.CalcInfo` instance """ # assert that the potential and structure have the same kind elements if self.inputs.potential.allowed_element_names is not None and not set( k.symbol for k in self.inputs.structure.kinds ).issubset(self.inputs.potential.allowed_element_names): raise ValidationError( "the structure and potential are not compatible (different kind elements)" ) # Setup structure structure_txt, struct_transform = generate_lammps_structure( self.inputs.structure, self.inputs.potential.atom_style ) with open( tempfolder.get_abs_path(self.options.cell_transform_filename), "w+b" ) as handle: np.save(handle, struct_transform) if "parameters" in self.inputs: parameters = self.inputs.parameters else: parameters = Dict() # Setup input parameters input_txt = self.create_main_input_content( parameter_data=parameters, potential_data=self.inputs.potential, kind_symbols=[kind.symbol for kind in self.inputs.structure.kinds], structure_filename=self._INPUT_STRUCTURE, trajectory_filename=self.options.trajectory_suffix, system_filename=self.options.system_suffix, restart_filename=self.options.restart_filename, ) input_filename = tempfolder.get_abs_path(self._INPUT_FILE_NAME) with open(input_filename, "w") as infile: infile.write(input_txt) self.validate_parameters(parameters, self.inputs.potential) retrieve_list, retrieve_temporary_list = self.get_retrieve_lists() retrieve_list.extend( [self.options.output_filename, self.options.cell_transform_filename] ) # prepare extra files if needed self.prepare_extra_files(tempfolder, self.inputs.potential) # =========================== dump to file ============================= structure_filename = tempfolder.get_abs_path(self._INPUT_STRUCTURE) with open(structure_filename, "w") as infile: infile.write(structure_txt) for name, content in self.inputs.potential.get_external_files().items(): fpath = tempfolder.get_abs_path(name) with open(fpath, "w") as infile: infile.write(content) # ============================ calcinfo ================================ codeinfo = CodeInfo() codeinfo.cmdline_params = list(self._cmdline_params) codeinfo.code_uuid = self.inputs.code.uuid codeinfo.withmpi = self.metadata.options.withmpi codeinfo.stdout_name = self._stdout_name calcinfo = CalcInfo() calcinfo.uuid = self.uuid calcinfo.retrieve_list = retrieve_list calcinfo.retrieve_temporary_list = retrieve_temporary_list calcinfo.codes_info = [codeinfo] return calcinfo
def prepare_for_submission(self, tempfolder): # Setup template with open(self.inputs.template, 'r') as tempfile: temp_contents = tempfile.read() lmp_template = Template(temp_contents) # # check variables # for variable in self.inputs.variables.values(): # if not isinstance(variable, list): # raise TypeError('Values in variables must be list') # check kinds if 'kinds' in self.inputs: kind_var = { kind: kind_index + 1 for kind_index, kind in enumerate(self.inputs.kinds) } lmp_template = Template(lmp_template.safe_substitute(**kind_var)) for i, case in enumerate(self.inputs.cases): structure = case.pop('structure') if isinstance(structure, StructureData): structure_txt, struct_transform = generate_lammps_structure( structure, kinds=self.inputs.kinds) elif isinstance(structure, SinglefileData): structure_txt = structure.get_content() else: raise TypeError( 'Input structure must be StructureData or SinglefileData') input_txt = lmp_template.safe_substitute(**case) # ========================= dump to file =========================== tempfolder.get_subfolder(i, create=True) input_filename = tempfolder.get_abs_path( f'{i}/{self._INPUT_FILE_NAME}') with open(input_filename, 'w') as infile: infile.write(input_txt) structure_filename = tempfolder.get_abs_path( f'{i}/{self._INPUT_STRUCTURE}') with open(structure_filename, 'w') as infile: infile.write(structure_txt) case_filename = tempfolder.get_abs_path(f'{i}/case.json') case.update({'structure pk': structure.pk}) with open(case_filename, 'w') as infile: json.dump(case, infile, sort_keys=True, indent=2) # ============================ calcinfo ================================ settings = self.inputs.settings.get_dict() \ if 'settings' in self.inputs else {} codeinfo = CodeInfo() codeinfo.cmdline_params = self._cmdline_params codeinfo.code_uuid = self.inputs.code.uuid codeinfo.stdout_name = self._stdout_name codeinfo.join_files = True calcinfo = CalcInfo() calcinfo.uuid = self.uuid calcinfo.prepend_text = (f'for i in $(seq 0 {i})\n' 'do\n' 'cd "${i}" || exit') calcinfo.append_text = ('cd ..\n' 'done') calcinfo.cmdline_params = codeinfo.cmdline_params calcinfo.stdin_name = self._INPUT_FILE_NAME calcinfo.stdout_name = self._stdout_name calcinfo.retrieve_list = self._retrieve_list + [ self.options.output_filename ] calcinfo.retrieve_list += settings.pop('additional_retrieve_list', []) calcinfo.retrieve_temporary_list = self._retrieve_temporary_list calcinfo.codes_info = [codeinfo] # =========================== local_copy_list ========================== if 'file' in self.inputs: calcinfo.local_copy_list = [] for name, obj in self.inputs.file.items(): calcinfo.local_copy_list.append( (obj.uuid, obj.filename, f'{name}.pb')) return calcinfo
def prepare_for_submission(self, tempfolder): # Setup structure if isinstance(self.inputs.structure, StructureData): structure_txt, struct_transform = generate_lammps_structure( self.inputs.structure, kinds=self.inputs.kinds) elif isinstance(self.inputs.structure, SinglefileData): structure_txt = self.inputs.structure.get_content() else: raise TypeError( 'Input structure must be StructureData or SinglefileData') with open(self.inputs.template, 'r') as tempfile: temp_contents = tempfile.read() init_temp = Template(temp_contents) input_txt = init_temp.safe_substitute(**self.inputs.variables) if 'kinds' in self.inputs: kind_temp = Template(input_txt) kind_var = { kind: kind_index + 1 for kind_index, kind in enumerate(self.inputs.kinds) } input_txt = kind_temp.safe_substitute(**kind_var) # =========================== dump to file ============================= input_filename = tempfolder.get_abs_path(self._INPUT_FILE_NAME) with open(input_filename, 'w') as infile: infile.write(input_txt) structure_filename = tempfolder.get_abs_path(self._INPUT_STRUCTURE) with open(structure_filename, 'w') as infile: infile.write(structure_txt) # ============================ calcinfo ================================ settings = self.inputs.settings.get_dict() \ if 'settings' in self.inputs else {} codeinfo = CodeInfo() codeinfo.cmdline_params = self._cmdline_params codeinfo.code_uuid = self.inputs.code.uuid codeinfo.stdout_name = self._stdout_name codeinfo.join_files = True calcinfo = CalcInfo() calcinfo.uuid = self.uuid calcinfo.cmdline_params = codeinfo.cmdline_params calcinfo.stdin_name = self._INPUT_FILE_NAME calcinfo.stdout_name = self._stdout_name calcinfo.retrieve_list = self._retrieve_list + [ self.options.output_filename ] calcinfo.retrieve_list += settings.pop('additional_retrieve_list', []) calcinfo.retrieve_temporary_list = self._retrieve_temporary_list calcinfo.codes_info = [codeinfo] # =========================== local_copy_list ========================== if 'file' in self.inputs: calcinfo.local_copy_list = [] for name, obj in self.inputs.file.items(): calcinfo.local_copy_list.append( (obj.uuid, obj.filename, f'{name}.pb')) return calcinfo
def prepare_for_submission(self, folder): """ Create the input files from the input nodes passed to this instance of the `CalcJob`. """ # pylint: disable=too-many-locals # Generate the content of the structure file based on the input # structure structure_filecontent, _ = generate_lammps_structure( self.inputs.structure, self.inputs.potential.atom_style, ) # Get the name of the structure file and write it to the remote folder _structure_filename = self.inputs.metadata.options.structure_filename with folder.open(_structure_filename, 'w') as handle: handle.write(structure_filecontent) # Get the parameters dictionary so that they can be used for creating # the input file _parameters = self.inputs.parameters.get_dict() # Get the name of the trajectory file _trajectory_filename = self.inputs.metadata.options.trajectory_filename # Get the name of the variables file _variables_filename = self.inputs.metadata.options.variables_filename # Get the name of the restart file _restart_filename = self.inputs.metadata.options.restart_filename # Get the name of the output file _output_filename = self.inputs.metadata.options.output_filename # Get the name of the logfile file _logfile_filename = self.inputs.metadata.options.logfile_filename # If there is a restartfile set its name to the input variables and # write it in the remote folder if 'input_restartfile' in self.inputs: _read_restart_filename = self._DEFAULT_READ_RESTART_FILENAME with folder.open(_read_restart_filename, 'wb') as handle: handle.write(self.inputs.input_restartfile.get_content()) else: _read_restart_filename = None # Write the input file content. This function will also check the # sanity of the passed paremters when comparing it to a schema input_filecontent = generate_input_file( potential=self.inputs.potential, structure=self.inputs.structure, parameters=_parameters, restart_filename=_restart_filename, trajectory_filename=_trajectory_filename, variables_filename=_variables_filename, read_restart_filename=_read_restart_filename, ) # Get the name of the input file, and write it to the remote folder _input_filename = self.inputs.metadata.options.input_filename with folder.open(_input_filename, 'w') as handle: handle.write(input_filecontent) # Write the potential to the remote folder with folder.open(self._DEFAULT_POTENTIAL_FILENAME, 'w') as handle: handle.write(self.inputs.potential.get_content()) codeinfo = datastructures.CodeInfo() # Command line variables to ensure that the input file from LAMMPS can # be read codeinfo.cmdline_params = [ '-in', _input_filename, '-log', _logfile_filename ] # Set the code uuid codeinfo.code_uuid = self.inputs.code.uuid # Set the name of the stdout codeinfo.stdout_name = _output_filename # Set whether or not one is running with MPI codeinfo.withmpi = self.inputs.metadata.options.withmpi # Generate the datastructure for the calculation information calcinfo = datastructures.CalcInfo() calcinfo.uuid = str(self.uuid) # Set the files that must be retrieved calcinfo.retrieve_list = [] calcinfo.retrieve_list.append(_output_filename) calcinfo.retrieve_list.append(_logfile_filename) calcinfo.retrieve_list.append(_restart_filename) calcinfo.retrieve_list.append(_variables_filename) calcinfo.retrieve_list.append(_trajectory_filename) # Set the information of the code into the calculation datastructure calcinfo.codes_info = [codeinfo] return calcinfo
def prepare_for_submission(self, tempfolder): """Create the input files from the input nodes passed to this instance of the `CalcJob`. :param tempfolder: an `aiida.common.folders.Folder` to temporarily write files on disk :return: `aiida.common.CalcInfo` instance """ # assert that the potential and structure have the same kind elements if [k.symbol for k in self.inputs.structure.kinds] != self.inputs.potential.kind_elements: raise ValidationError("the structure and potential are not compatible (different kind elements)") # Setup potential potential_txt = self.inputs.potential.get_potential_file() # Setup structure structure_txt, struct_transform = generate_lammps_structure( self.inputs.structure, self.inputs.potential.atom_style) with open(tempfolder.get_abs_path(self.options.cell_transform_filename), 'w+b') as handle: np.save(handle, struct_transform) if "parameters" in self.inputs: parameters = self.inputs.parameters else: parameters = Dict() pdict = parameters.get_dict() # Check lammps version date in parameters lammps_date = convert_date_string( pdict.get("lammps_version", '11 Aug 2017')) # Setup input parameters input_txt = self._generate_input_function( parameters=parameters, potential_obj=self.inputs.potential, structure_filename=self._INPUT_STRUCTURE, trajectory_filename=self.options.trajectory_name, info_filename=self.options.info_filename, restart_filename=self.options.restart_filename, add_thermo_keywords=pdict.get("thermo_keywords", []), version_date=lammps_date) input_filename = tempfolder.get_abs_path(self._INPUT_FILE_NAME) with open(input_filename, 'w') as infile: infile.write(input_txt) self.validate_parameters(parameters, self.inputs.potential) # prepare extra files if needed self.prepare_extra_files(tempfolder, self.inputs.potential) # =========================== dump to file ============================= structure_filename = tempfolder.get_abs_path(self._INPUT_STRUCTURE) with open(structure_filename, 'w') as infile: infile.write(structure_txt) if potential_txt is not None: potential_filename = tempfolder.get_abs_path( self.inputs.potential.potential_filename) with open(potential_filename, 'w') as infile: infile.write(potential_txt) # ============================ calcinfo ================================ codeinfo = CodeInfo() codeinfo.cmdline_params = self._cmdline_params codeinfo.code_uuid = self.inputs.code.uuid codeinfo.withmpi = False # Set lammps openmpi environment properly codeinfo.stdout_name = self._stdout_name calcinfo = CalcInfo() calcinfo.uuid = self.uuid calcinfo.retrieve_list = self._retrieve_list + [ self.options.output_filename, self.options.cell_transform_filename] calcinfo.retrieve_temporary_list = self._retrieve_temporary_list calcinfo.codes_info = [codeinfo] return calcinfo
def test_generate(db_test_app, get_structure_data, structure, file_regression): structure = get_structure_data(structure) text, transform = generate_lammps_structure(structure, round_dp=8) file_regression.check(text)