Source code for aiida_crystal17.calculations.cry_basic

"""
Plugin to create a CRYSTAL17 output file from a supplied input file.
"""
import os

from aiida.common.datastructures import (CalcInfo, CodeInfo)
from aiida.common.exceptions import (InputValidationError, ValidationError)
from aiida.common.utils import classproperty
from aiida.orm.calculation.job import JobCalculation
from aiida.orm import DataFactory
SinglefileData = DataFactory('singlefile')


[docs]class CryBasicCalculation(JobCalculation): """ AiiDA calculation plugin wrapping the runcry17 executable. """ def _init_internal_params(self): # pylint: disable=useless-super-delegation """ Init internal parameters at class load time """ # reuse base class function super(CryBasicCalculation, self)._init_internal_params() # default input and output files self._DEFAULT_INPUT_FILE = 'main.d12' self._DEFAULT_EXTERNAL_FILE = 'main.gui' self._DEFAULT_OUTPUT_FILE = 'main.out' # parser entry point defined in setup.json self._default_parser = 'crystal17.basic' @classproperty def _use_methods(cls): """ Add use_* methods for calculations. Code below enables the usage my_calculation.use_parameters(my_parameters) """ use_dict = JobCalculation._use_methods use_dict.update({ "input_file": { 'valid_types': SinglefileData, 'additional_parameter': None, 'linkname': 'input_file', 'docstring': "the input .d12 file content." }, "input_external": { 'valid_types': SinglefileData, 'additional_parameter': None, 'linkname': 'input_external', 'docstring': "optional input .gui (fort.34) file content (for use with EXTERNAL keyword)." }, # TODO retrieve .f9 / .f98 from remote folder (for GUESSP or RESTART) # "parent_folder": { # 'valid_types': RemoteData, # 'additional_parameter': None, # 'linkname': 'parent_calc_folder', # 'docstring': ("Use a remote folder as parent folder (for " # "restarts and similar"), # }, }) return use_dict def _prepare_for_submission(self, tempfolder, inputdict): """ Create input files. :param tempfolder: aiida.common.folders.Folder subclass where the plugin should put all its files. :param inputdict: dictionary of the input nodes as they would be returned by get_inputs_dict See https://aiida-core.readthedocs.io/en/latest/ developer_guide/devel_tutorial/code_plugin_qe.html#step-3-prepare-a-text-input for a description of its finction and inputs """ # read inputs # we expect "code" and "input_file" try: code = inputdict.pop(self.get_linkname('code')) except KeyError: raise InputValidationError("No code specified for this " "calculation") try: infile = inputdict.pop(self.get_linkname('input_file')) except KeyError: raise InputValidationError("Missing input_file") if not isinstance(infile, SinglefileData): raise InputValidationError("input_file not of type SinglefileData") try: ingui = inputdict.pop(self.get_linkname('input_external')) external_geom = True except KeyError: ingui = None external_geom = False if external_geom and not isinstance(ingui, SinglefileData): raise InputValidationError( "input_external not of type SinglefileData") if inputdict: raise ValidationError( "Unknown additional inputs: {}".format(inputdict)) # Prepare CodeInfo object for aiida, describes how a code has to be executed codeinfo = CodeInfo() codeinfo.code_uuid = code.uuid codeinfo.cmdline_params = [ os.path.splitext(self._DEFAULT_INPUT_FILE)[0] ] # codeinfo.stdout_name = self._DEFAULT_OUTPUT_FILE # this file doesn't actually come from stdout codeinfo.withmpi = self.get_withmpi() # Prepare CalcInfo object for aiida calcinfo = CalcInfo() calcinfo.uuid = self.uuid calcinfo.codes_info = [codeinfo] calcinfo.local_copy_list = [[ infile.get_file_abs_path(), self._DEFAULT_INPUT_FILE ]] if external_geom: calcinfo.local_copy_list.append( [ingui.get_file_abs_path(), self._DEFAULT_EXTERNAL_FILE]) calcinfo.remote_copy_list = [] calcinfo.retrieve_list = [self._DEFAULT_OUTPUT_FILE] # TODO .gui won't be available for scf runs, will the computation fail if it can't find a file in retrieve list? # calcinfo.retrieve_list.append(self._DEFAULT_EXTERNAL_FILE) calcinfo.retrieve_temporary_list = [] # TODO set hpc options (i.e. calcinfo.num_machines, etc)? Doesn't seem required looking at aiida-quantumespresso # (see https://aiida-core.readthedocs.io/en/latest/_modules/aiida/common/datastructures.html) return calcinfo