예제 #1
0
    def test_kkr_from_kkr(self):
        """
        continue KKR calculation after a previous KKR calculation instead of starting from voronoi
        """
        from aiida.orm import Code, load_node
        from aiida.plugins import DataFactory
        from masci_tools.io.kkr_params import kkrparams
        from aiida_kkr.calculations.kkr import KkrCalculation
        Dict = DataFactory('dict')

        # load necessary files from db_dump files
        from aiida.tools.importexport import import_data
        import_data('files/db_dump_kkrcalc.tar.gz')
        kkr_calc = load_node('3058bd6c-de0b-400e-aff5-2331a5f5d566')

        # prepare computer and code (needed so that
        prepare_code(kkr_codename, codelocation, computername, workdir)

        # extract KKR parameter (add missing values)
        params_node = kkr_calc.inputs.parameters

        # load code from database and create new voronoi calculation
        code = Code.get_from_string(kkr_codename+'@'+computername)
        options = {'resources': {'num_machines':1, 'tot_num_mpiprocs':1}, 'queue_name': queuename}
        builder = KkrCalculation.get_builder()
        builder.code = code
        builder.metadata.options = options
        builder.parameters = params_node
        builder.parent_folder = kkr_calc.outputs.remote_folder
        builder.metadata.dry_run = True
        from aiida.engine import run
        run(builder)
예제 #2
0
 def _set_filenames_in(self, input_file_names):
     """
     helper function to set filenames from input_file_names dict
     also check if at least inputcard and potential are given
     """
     has_input_files = False
     if input_file_names is not None:
         has_input_files = True
         if input_file_names.get('input_file') is not None:
             self._INPUT_FILE_NAME = input_file_names.get('input_file')
         else:
             self.logger.info('KKRimporter: input_file not given!')
             has_input_files = False
         if input_file_names.get('potential_file') is not None:
             self._POTENTIAL = input_file_names.get('potential_file')
         else:
             self.logger.info('KKRimporter: potential_file not given!')
             has_input_files = False
         if input_file_names.get('shapefun_file') is not None:
             self._SHAPEFUN = input_file_names.get('shapefun_file')
         else:
             self._SHAPEFUN = KkrCalculation()._SHAPEFUN
     if not has_input_files:
         raise InputValidationError(
             'The input file_names has not been specified correctly.\n'
             'Please specify it using one of the following...\n '
             '(a) pass as a keyword argument to create_input_nodes\n'
             '    [create_input_nodes(input_file_names=your_file_names_dictionary)]\n'
             '(b) pass as a keyword argument when instantiating\n '
             '    [calc = KkrImporterCalculation(input_file_names={"input_file":"inputcard", "potential_file":"potential", ...}]\n'
             '(c) use the set_input_file_names method\n'
             '    [calc.set_input_file_name(your_file_names)]')
예제 #3
0
    def _get_pot_and_shape(self, imp_info, shapefun_path, shapes, impurity_potential, parent_calc_folder, tempfolder, structure):
        """
        write shapefun from impurity info and host shapefun and copy imp. potential
        """

        scoef_filename = os.path.join(tempfolder.get_abs_path(''), KkrCalculation()._SCOEF)
        imp_info_dict = imp_info.get_dict()
        Rcut = imp_info_dict.get('Rcut', None)
        hcut = imp_info_dict.get('hcut', -1.)
        cylinder_orient = imp_info_dict.get('cylinder_orient', [0., 0., 1.])
        ilayer_center = imp_info_dict.get('ilayer_center', 0)
        make_scoef(structure, Rcut, scoef_filename, hcut, cylinder_orient, ilayer_center)
        
        # create impurity shapefun
        shapefun_new_path = tempfolder.get_abs_path(self._SHAPEFUN)
        modify_potential().shapefun_from_scoef(scoef_filename, shapefun_path, shapes, shapefun_new_path)
            
        # find path to input potential
        if impurity_potential is not None:
            potfile = impurity_potential.get_file_abs_path()
        elif parent_calc_folder is not None:
            self.logger.info('parent_calc_folder {} {}'.format(parent_calc_folder, parent_calc_folder.get_inputs_dict()))
            retrieved = parent_calc_folder.get_inputs(node_type=JobCalculation)[0].get_outputs_dict().get('retrieved', None)
            self.logger.info('potfile {} {}'.format(retrieved, self._OUT_POTENTIAL))
            potfile = retrieved.get_abs_path(self._OUT_POTENTIAL)
        else:
            raise InputValidationError('ERROR in _get_pot_and_shape: neither impurity potential nor parent_calc_folder given!')
            
        # return path of input potential (added to copy_list)
        return potfile
예제 #4
0
 def _change_atominfo(self, imp_info, kkrflex_file_paths, tempfolder):
     """
     change kkrflex_atominfo to match impurity case
     """
     # read in atominfo file as it is written out
     with open(kkrflex_file_paths.get(KkrCalculation()._KKRFLEX_ATOMINFO)) as file:
         atominfo = file.readlines()
         
     #TODO implement logic to extract this info from imp_info
     replace_zatom_imp = []
     
     # read scoef for comparison with Rimp_rel
     scoef = []
     with open(tempfolder.get_abs_path(KkrCalculation()._SCOEF), 'r') as file:
         Nscoef = int(file.readline().split()[0])
         for iline in range(Nscoef):
             tmpline = file.readline().split()
             scoef.append([float(i) for i in tmpline[:3]])
     scoef = array(scoef)
     
     # find replaceZimp list from Zimp and Rimp_rel
     imp_info_dict = imp_info.get_dict()
     Zimp_list = imp_info_dict.get('Zimp')
     Rimp_rel_list = imp_info_dict.get('Rimp_rel', [[0,0,0]])
     for iatom in range(len(Zimp_list)):
         rtmp = Rimp_rel_list[iatom]
         diff = sqrt(sum((rtmp-scoef)**2, axis=1))
         Zimp = Zimp_list[iatom]
         ipos_replace = where(diff==diff.min())[0][0]
         replace_zatom_imp.append([ipos_replace, Zimp])
     
     for (iatom, zimp) in replace_zatom_imp:
         tmp = atominfo[iatom+4].split()
         x, y, z = float(tmp[0]), float(tmp[1]), float(tmp[2])
         zatom = float(tmp[3])
         virt, remove, lmax = int(tmp[4]), int(tmp[5]), int(tmp[6])
         zatom = zimp
         tmp = ' %24.16f %24.16f %24.16f %5.2f %4i %4i %4i\n'%(x, y, z, zatom, virt, remove, lmax)
         atominfo[iatom+4] = tmp
         
     # write atominfo file
     atominfo_path = tempfolder.get_abs_path(self._KKRFLEX_ATOMINFO)
     with open(atominfo_path, 'w') as file:
         file.writelines(atominfo)
예제 #5
0
    def _init_internal_params(self):
        """
        Init internal parameters at class load time
        """
        # reuse base class function
        super(KkrimpCalculation, self)._init_internal_params()
        
        # calculation plugin version
        self._CALCULATION_PLUGIN_VERSION = __version__

        # List of mandatory input files
        self._CONFIG = 'config.cfg'
        self._POTENTIAL = 'potential'
        self._KKRFLEX_GREEN = KkrCalculation()._KKRFLEX_GREEN
        self._KKRFLEX_TMAT = KkrCalculation()._KKRFLEX_TMAT
        self._KKRFLEX_ATOMINFO = KkrCalculation()._KKRFLEX_ATOMINFO
        self._KKRFLEX_INTERCELL_REF = KkrCalculation()._KKRFLEX_INTERCELL_REF
        self._KKRFLEX_INTERCELL_CMOMS = KkrCalculation()._KKRFLEX_INTERCELL_CMOMS

        # List of optional input files (may be mandatory for some setting in inputputcard)
        self._SHAPEFUN = 'shapefun'
        self._KKRFLEX_ANGLE = 'kkrflex_angle'
        self._KKRFLEX_LLYFAC = 'kkrflex_llyfac'
        
        # full list of kkrflex files
        self._ALL_KKRFLEX_FILES = KkrCalculation()._ALL_KKRFLEX_FILES
        self._ALL_KKRFLEX_FILES.append(self._KKRFLEX_ANGLE)
        self._ALL_KKRFLEX_FILES.append(self._KKRFLEX_LLYFAC)

        # List of output files that should always be present
        self._OUT_POTENTIAL = 'out_potential'
        self._OUTPUT_000 = 'out_log.000.txt'
        self._OUT_TIMING_000 = 'out_timing.000.txt'
        self._OUT_ENERGYSP = 'out_energysp_eV'
        self._OUT_ENERGYSP_PER_ATOM = 'out_energysp_per_atom_eV'
        self._OUT_ENERGYTOT = 'out_energytotal_eV'
        self._OUT_ENERGYTOT_PER_ATOM =  'out_energytotal_per_atom_eV'
        
        # Lift of output files that are retrieved if special conditions are fulfilled
        self._OUT_JIJDIJ = 'out_JijDij'
        self._OUT_JIJDIJ_LOCAL = 'out_JijDij_local'
        self._OUT_JIJMAT = 'out_Jijmatrix'
        self._OUT_JIJMAT_LOCAL = 'out_Jijmatrix_local'
        self._OUT_LDOS_BASE = 'out_ldos.atom=%2i_spin%i.dat'
        self._OUT_LDOS_INTERPOL_BASE = 'out_ldos.interpol.atom=%2i_spin%i.dat'
        self._OUT_LMDOS_BASE = 'out_lmdos.atom=%2i_spin%i.dat'
        self._OUT_LMDOS_INTERPOL_BASE = 'out_lmdos.interpol.atom=%2i_spin%i.dat'
        self._OUT_MAGNETICMOMENTS = 'out_magneticmoments'
        self._OUT_ORBITALMOMENTS = 'out_orbitalmoments'

        # template.product entry point defined in setup.json
        self._default_parser = 'kkr.kkrimpparser'
        
        # default names used within aiida (verdi calculation out(in)putcat)
        self._OUTPUT_FILE_NAME = 'out_kkrimp'
        self._INPUT_FILE_NAME = self._CONFIG
        self._DEFAULT_OUTPUT_FILE = self._OUTPUT_FILE_NAME # will be shown with outputcat
        self._DEFAULT_INPUT_FILE = self._INPUT_FILE_NAME # will be shown with inputcat
예제 #6
0
def get_inputs_kkrimporter(code,
                           remote,
                           options,
                           label='',
                           description='',
                           parameters=None,
                           serial=False):
    """
    Get the input for a voronoi calc.
    Wrapper for KkrProcess setting structure, code, options, label, description etc.
    """
    from aiida_kkr.calculations.kkr import KkrCalculation
    KkrProcess = KkrCalculation.process()

    # then reuse common inputs setter
    inputs = get_inputs_common(KkrProcess, code, remote, None, options, label,
                               description, parameters, serial)

    return inputs
예제 #7
0
    def test_kkrflex(self):
        """
        test kkrflex file writeout (GF writeout for impurity calculation)
        """
        from aiida.orm import Code, load_node
        from aiida.plugins import DataFactory
        from masci_tools.io.kkr_params import kkrparams
        from aiida_kkr.calculations.kkr import KkrCalculation
        Dict = DataFactory('dict')

        # load necessary files from db_dump files
        from aiida.tools.importexport import import_data
        import_data('files/db_dump_kkrcalc.tar.gz')

        # first load parent voronoi calculation
        kkr_calc = load_node('3058bd6c-de0b-400e-aff5-2331a5f5d566')

        # extract KKR parameter (add KKRFLEX option)
        params_node = kkr_calc.inputs.parameters
        params = params_node.get_dict()
        params['RUNOPT'] = ['KKRFLEX']
        params_node = Dict(dict=params)

        # create an impurity_info node
        imp_info = Dict(dict={'Rcut':1.01, 'ilayer_center': 0, 'Zimp':[29.]})

        # prepare computer and code (needed so that
        prepare_code(kkr_codename, codelocation, computername, workdir)

        # load code from database and create new voronoi calculation
        code = Code.get_from_string(kkr_codename+'@'+computername)
        options = {'resources': {'num_machines':1, 'tot_num_mpiprocs':1}, 'queue_name': queuename}
        builder = KkrCalculation.get_builder()
        builder.code = code
        builder.metadata.options = options
        builder.parameters = params_node
        builder.parent_folder = kkr_calc.outputs.remote_folder
        builder.impurity_info = imp_info
        builder.metadata.dry_run = True
        from aiida.engine import run
        run(builder)
예제 #8
0
    def test_kkr_qdos(self):
        """
        run bandstructure calculation
        """
        from aiida.orm import Code, load_node
        from aiida.plugins import DataFactory
        from masci_tools.io.kkr_params import kkrparams
        from aiida_kkr.calculations.kkr import KkrCalculation
        Dict = DataFactory('dict')
        KpointsData = DataFactory('array.kpoints')

        # define k-path
        kpoints = KpointsData()
        kpoints.set_kpoints([[0,0,0],[0.1,0,0],[0.2,0,0],[0.3,0,0],[0.4,0,0]])
        kpoints.set_cell([[1.0,0,0],[0,1.0,0],[0,0,1.0]])

        # load necessary files from db_dump files
        from aiida.tools.importexport import import_data
        import_data('files/db_dump_kkrcalc.tar.gz')

        # prepare computer and code (needed so that
        prepare_code(kkr_codename, codelocation, computername, workdir)

        # first load parent voronoi calculation
        kkr_calc = load_node('3058bd6c-de0b-400e-aff5-2331a5f5d566')

        # extract KKR parameter (add missing values)
        params_node = kkr_calc.inputs.parameters

        # load code from database and create new voronoi calculation
        code = Code.get_from_string(kkr_codename+'@'+computername)
        options = {'resources': {'num_machines':1, 'tot_num_mpiprocs':1}, 'queue_name': queuename}
        builder = KkrCalculation.get_builder()
        builder.code = code
        builder.metadata.options = options
        builder.parameters = params_node
        builder.parent_folder = kkr_calc.outputs.remote_folder
        builder.kpoints = kpoints
        builder.metadata.dry_run = True
        from aiida.engine import run
        run(builder)
예제 #9
0
def get_inputs_kkr(code,
                   remote,
                   options,
                   label='',
                   description='',
                   parameters=None,
                   serial=False):
    """
    Get the input for a voronoi calc.
    Wrapper for KkrProcess setting structure, code, options, label, description etc.
    :param code: a valid KKRcode installation (e.g. input from Code.get_from_string('codename@computername'))
    :param remote: remote directory of parent calculation (Voronoi or previous KKR calculation)
    
    """
    from aiida_kkr.calculations.kkr import KkrCalculation
    KkrProcess = KkrCalculation.process()

    # then reuse common inputs setter
    inputs = get_inputs_common(KkrProcess, code, remote, None, options, label,
                               description, parameters, serial)

    return inputs
예제 #10
0
 def set_output_file_names(self, output_file_names):
     """
     Set the file names of the job's output files (e.g. ``'output.000.txt'`` etc.).
     
     :param output_file_names: The dictionary of file names of file containing the job's
         outputs.
     :type output_file_names: dict
     
     Keys of output_file_names dict should be one or more of:
         
     * ``'out_file'``
     * ``'out_potential_file'``
     * ``'out_nonco_angles_file'``
     * ``'output_0_file'``
     * ``'output_000_file'``
     * ``'output_2_file'``
     * ``'timing_file'``
     
     :note: In a filename is not given, the default value of aiida_kkr.calculations.kkr are used
     """
     if self._OUTPUT_FILE_NAMES is None:
         if output_file_names is None:  #set default values if nothing is chosen
             self._OUT_POTENTIAL = self._POTENTIAL
             self._DEFAULT_OUTPUT_FILE = KkrCalculation(
             )._DEFAULT_OUTPUT_FILE
             self._NONCO_ANGLES_OUT = KkrCalculation()._NONCO_ANGLES_OUT
             self._OUTPUT_0_INIT = KkrCalculation()._OUTPUT_0_INIT
             self._OUTPUT_000 = KkrCalculation()._OUTPUT_000
             self._OUTPUT_2 = KkrCalculation()._OUTPUT_2
             self._OUT_TIMING_000 = KkrCalculation()._OUT_TIMING_000
             output_file_names = {
                 'out_potential_file': self._OUT_POTENTIAL,
                 'out_file': self._DEFAULT_OUTPUT_FILE,
                 'out_nonco_angles_file': self._NONCO_ANGLES_OUT,
                 'output_0_file': self._OUTPUT_0_INIT,
                 'output_000_file': self._OUT_TIMING_000,
                 'output_2_file': self._OUTPUT_2,
                 'timing_file': self._OUT_TIMING_000
             }
         else:
             self.logger.info(
                 'setting output_file_names: {}'.format(output_file_names))
             self._set_filenames_out(output_file_names)
         # finally set ourput_file_names as class attribute
         self._set_attr('output_file_names', output_file_names)
예제 #11
0
    def test_kkr_from_voronoi(self):
        """
        simple Cu noSOC, FP, lmax2 full example
        """
        from aiida.orm import Code, load_node
        from aiida.plugins import DataFactory
        from masci_tools.io.kkr_params import kkrparams
        from aiida_kkr.calculations.kkr import KkrCalculation
        Dict = DataFactory('dict')

        # load necessary files from db_dump files
        from aiida.tools.importexport import import_data
        import_data('files/db_dump_vorocalc.tar.gz', extras_mode_existing='nnl')

        # prepare computer and code (needed so that
        prepare_code(kkr_codename, codelocation, computername, workdir)

        # first load parent voronoi calculation
        voro_calc = load_node('559b9d9b-3525-402e-9b24-ecd8b801853c')

        # extract and update KKR parameter (add missing values)
        params = kkrparams(**voro_calc.inputs.parameters.get_dict())
        params.set_multiple_values(RMAX=7., GMAX=65.)
        params_node = Dict(dict=params.get_dict())

        # load code from database and create new voronoi calculation
        #code = Code.get_from_string(codename)
        code = Code.get_from_string(kkr_codename+'@'+computername)
        options = {'resources': {'num_machines':1, 'tot_num_mpiprocs':1}, 'queue_name': queuename}
        builder = KkrCalculation.get_builder()
        builder.code = code
        builder.metadata.options = options
        builder.parameters = params_node
        builder.parent_folder = voro_calc.outputs.remote_folder
        builder.metadata.dry_run = True
        from aiida.engine import run
        run(builder)
예제 #12
0
 def _set_filenames_out(self, output_file_names):
     """
     helper function that sets the output file names from the output_file_names dictionary
     """
     if output_file_names is not None and output_file_names.get(
             'out_potential_file') is not None:
         self._OUT_POTENTIAL = output_file_names.get('out_potential_file')
     else:
         self._OUT_POTENTIAL = self._POTENTIAL
     #raise InputValidationError('test: {}'.format(self._OUT_POTENTIAL))
     if output_file_names is not None:
         if output_file_names.get('out_file') is not None:
             self._DEFAULT_OUTPUT_FILE = output_file_names.get('out_file')
         else:
             self._DEFAULT_OUTPUT_FILE = KkrCalculation(
             )._DEFAULT_OUTPUT_FILE
         if output_file_names.get('out_nonco_angles_file') is not None:
             self._NONCO_ANGLES_OUT = output_file_names.get(
                 'out_nonco_angles_file')
         else:
             self._NONCO_ANGLES_OUT = KkrCalculation()._NONCO_ANGLES_OUT
         if output_file_names.get('output_0_file') is not None:
             self._OUTPUT_0_INIT = output_file_names.get('output_0_file')
         else:
             self._OUTPUT_0_INIT = KkrCalculation()._OUTPUT_0_INIT
         if output_file_names.get('output_000_file') is not None:
             self._OUTPUT_000 = output_file_names.get('output_000_file')
         else:
             self._OUTPUT_000 = KkrCalculation()._OUTPUT_000
         if output_file_names.get('output_2_file') is not None:
             self._OUTPUT_2 = output_file_names.get('output_2_file')
         else:
             self._OUTPUT_2 = KkrCalculation()._OUTPUT_2
         if output_file_names.get('timing_file') is not None:
             self._OUT_TIMING_000 = output_file_names.get('timing_file')
         else:
             self._OUT_TIMING_000 = KkrCalculation()._OUT_TIMING_000
예제 #13
0
파일: dos.py 프로젝트: broeder-j/aiida-kkr
from aiida_kkr.calculations.voro import VoronoiCalculation
from aiida.orm.calculation.job import JobCalculation
from aiida.common.datastructures import calc_states
from aiida.orm import WorkCalculation
from aiida.common.exceptions import InputValidationError

__copyright__ = (u"Copyright (c), 2017, Forschungszentrum Jülich GmbH, "
                 "IAS-1/PGI-1, Germany. All rights reserved.")
__license__ = "MIT license, see LICENSE.txt file"
__version__ = "0.4"
__contributors__ = u"Philipp Rüßmann"

RemoteData = DataFactory('remote')
StructureData = DataFactory('structure')
ParameterData = DataFactory('parameter')
KkrProcess = KkrCalculation.process()


class kkr_dos_wc(WorkChain):
    """
    Workchain a DOS calculation with KKR starting from the remoteData node 
    of a previous calculation (either Voronoi or KKR).

    :param wf_parameters: (ParameterData); Workchain specifications
    :param remote_data: (RemoteData), mandatory; from a KKR or Vornoi calculation
    :param kkr: (Code), mandatory; KKR code running the dos calculation

    :return result_kkr_dos_wc: (ParameterData), Information of workflow results 
        like Success, last result node, list with convergence behavior
    """
예제 #14
0
class KkrimpCalculation(JobCalculation):
    """
    AiiDA calculation plugin for a KKR calculation
    .
    """

    def _init_internal_params(self):
        """
        Init internal parameters at class load time
        """
        # reuse base class function
        super(KkrimpCalculation, self)._init_internal_params()
        
        # calculation plugin version
        self._CALCULATION_PLUGIN_VERSION = __version__

        # List of mandatory input files
        self._CONFIG = 'config.cfg'
        self._POTENTIAL = 'potential'
        self._KKRFLEX_GREEN = KkrCalculation()._KKRFLEX_GREEN
        self._KKRFLEX_TMAT = KkrCalculation()._KKRFLEX_TMAT
        self._KKRFLEX_ATOMINFO = KkrCalculation()._KKRFLEX_ATOMINFO
        self._KKRFLEX_INTERCELL_REF = KkrCalculation()._KKRFLEX_INTERCELL_REF
        self._KKRFLEX_INTERCELL_CMOMS = KkrCalculation()._KKRFLEX_INTERCELL_CMOMS

        # List of optional input files (may be mandatory for some setting in inputputcard)
        self._SHAPEFUN = 'shapefun'
        self._KKRFLEX_ANGLE = 'kkrflex_angle'
        self._KKRFLEX_LLYFAC = 'kkrflex_llyfac'
        
        # full list of kkrflex files
        self._ALL_KKRFLEX_FILES = KkrCalculation()._ALL_KKRFLEX_FILES
        self._ALL_KKRFLEX_FILES.append(self._KKRFLEX_ANGLE)
        self._ALL_KKRFLEX_FILES.append(self._KKRFLEX_LLYFAC)

        # List of output files that should always be present
        self._OUT_POTENTIAL = 'out_potential'
        self._OUTPUT_000 = 'out_log.000.txt'
        self._OUT_TIMING_000 = 'out_timing.000.txt'
        self._OUT_ENERGYSP = 'out_energysp_eV'
        self._OUT_ENERGYSP_PER_ATOM = 'out_energysp_per_atom_eV'
        self._OUT_ENERGYTOT = 'out_energytotal_eV'
        self._OUT_ENERGYTOT_PER_ATOM =  'out_energytotal_per_atom_eV'
        
        # Lift of output files that are retrieved if special conditions are fulfilled
        self._OUT_JIJDIJ = 'out_JijDij'
        self._OUT_JIJDIJ_LOCAL = 'out_JijDij_local'
        self._OUT_JIJMAT = 'out_Jijmatrix'
        self._OUT_JIJMAT_LOCAL = 'out_Jijmatrix_local'
        self._OUT_LDOS_BASE = 'out_ldos.atom=%2i_spin%i.dat'
        self._OUT_LDOS_INTERPOL_BASE = 'out_ldos.interpol.atom=%2i_spin%i.dat'
        self._OUT_LMDOS_BASE = 'out_lmdos.atom=%2i_spin%i.dat'
        self._OUT_LMDOS_INTERPOL_BASE = 'out_lmdos.interpol.atom=%2i_spin%i.dat'
        self._OUT_MAGNETICMOMENTS = 'out_magneticmoments'
        self._OUT_ORBITALMOMENTS = 'out_orbitalmoments'

        # template.product entry point defined in setup.json
        self._default_parser = 'kkr.kkrimpparser'
        
        # default names used within aiida (verdi calculation out(in)putcat)
        self._OUTPUT_FILE_NAME = 'out_kkrimp'
        self._INPUT_FILE_NAME = self._CONFIG
        self._DEFAULT_OUTPUT_FILE = self._OUTPUT_FILE_NAME # will be shown with outputcat
        self._DEFAULT_INPUT_FILE = self._INPUT_FILE_NAME # will be shown with inputcat

    @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({
            "parameters": {
                'valid_types': ParameterData,
                'additional_parameter': None,
                'linkname': 'parameters',
                'docstring':
                ("Use a node that specifies the input parameters (calculation settings)")
                },
            "host_Greenfunction_folder": {
                'valid_types': RemoteData,
                'additional_parameter': None,
                'linkname': 'GFhost_folder',
                'docstring':
                ("Use a node that specifies the host KKR calculation contaning the host Green function and tmatrix (KkrCalculation with impurity_info input)")
                },
            "impurity_potential": {
                'valid_types': SinglefileData,
                'additional_parameter': None,
                'linkname': 'potential',
                'docstring':
                ("Use a node contains the input potential")
                },
            "parent_calc_folder": {
                'valid_types': RemoteData,
                'additional_parameter': None,
                'linkname': 'parent_calc_folder',
                'docstring':
                ("Use a node that specifies a parent KKRimp calculation")
                }
            })
        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
        """
        # Check inputdict and extrace nodes
        tmp = self._check_and_extract_input_nodes(inputdict)
        parameters = tmp[0]
        code = tmp[1]
        imp_info = tmp[2]
        kkrflex_file_paths = tmp[3]
        shapefun_path = tmp[4]
        shapes = tmp[5]
        host_parent_calc = tmp[6]
        params_host = tmp[7]
        impurity_potential = tmp[8]
        parent_calc_folder = tmp[9]
        structure = tmp[10]
        
        # Prepare input files for KKRimp calculation
        # 1. fill kkr params for KKRimp, write config file
        self._extract_and_write_config(parent_calc_folder, params_host, parameters, tempfolder)
        # 2. write shapefun from impurity info and host shapefun and copy imp. potential
        potfile = self._get_pot_and_shape(imp_info, shapefun_path, shapes, impurity_potential, parent_calc_folder, tempfolder, structure)
        # 3. change kkrflex_atominfo to match impurity case
        self._change_atominfo(imp_info, kkrflex_file_paths, tempfolder)
        
        # prepare copy and retrieve lists
        local_copy_list = [(potfile, self._POTENTIAL)]
        for key in kkrflex_file_paths.keys():
            if key!=self._KKRFLEX_ATOMINFO:
                src_path = kkrflex_file_paths[key]
                dst_path = key
                local_copy_list.append((src_path, dst_path))
                
        retrieve_list = [self._OUTPUT_FILE_NAME, self._CONFIG, self._KKRFLEX_ATOMINFO, 
                         self._SHAPEFUN, self._KKRFLEX_ANGLE, self._KKRFLEX_LLYFAC, 
                         self._OUT_POTENTIAL, self._OUTPUT_000, self._OUT_TIMING_000,
                         self._OUT_ENERGYSP_PER_ATOM, self._OUT_ENERGYTOT_PER_ATOM]

        # retrieve l(m)dos files
        runopts = parameters.get_dict().get('RUNFLAG')
        if runopts is None:
            runopts = []
        testopts = parameters.get_dict().get('TESTFLAG')
        if testopts is None:
            testopts = []
        allopts = runopts+testopts
        if 'lmdos' in allopts or 'ldos' in allopts:
            file = open(tempfolder.get_abs_path(self._CONFIG))
            config = file.readlines()
            file.close()
            itmp = search_string('NSPIN', config)
            if itmp>=0:
                nspin = int(config[itmp].split()[-1])
            else:
                raise ValueError("Could not extract NSPIN value from config.cfg")
            file = open(tempfolder.get_abs_path(self._KKRFLEX_ATOMINFO))
            atominfo = file.readlines()
            file.close()
            itmp = search_string('NATOM', atominfo)
            if itmp>=0:
                natom = int(atominfo[itmp+1].split()[0])
            else:
                raise ValueError("Could not extract NATOM value from kkrflex_atominfo")
            for iatom in range(1,natom+1):
                for ispin in range(1,nspin+1):
                    retrieve_list.append((self._OUT_LDOS_BASE%(iatom, ispin)).replace(' ', '0'))
                    retrieve_list.append((self._OUT_LDOS_INTERPOL_BASE%(iatom, ispin)).replace(' ', '0'))
                    retrieve_list.append((self._OUT_LMDOS_BASE%(iatom, ispin)).replace(' ', '0'))
                    retrieve_list.append((self._OUT_LMDOS_INTERPOL_BASE%(iatom, ispin)).replace(' ', '0'))
        
        # Prepare CalcInfo to be returned to aiida (e.g. retreive_list etc.)
        calcinfo = CalcInfo()
        calcinfo.uuid = self.uuid
        calcinfo.local_copy_list = local_copy_list
        calcinfo.remote_copy_list = []
        calcinfo.retrieve_list = retrieve_list

        codeinfo = CodeInfo()
        codeinfo.cmdline_params = []
        codeinfo.stdout_name = self._OUTPUT_FILE_NAME
        codeinfo.code_uuid = code.uuid
        calcinfo.codes_info = [codeinfo]

        return calcinfo
        
    #####################################################
    # helper functions
    
    def _get_and_verify_hostfiles(self, inputdict):
        """
        Check inputdict for host_Greenfunction_folder and extract impurity_info, paths to kkrflex-files and path of shapefun file
        
        :param inputdict: input dictionary containing all input nodes to KkrimpCalculation
        :returns: 
            * imp_info: ParameterData node containing impurity information like position, Z_imp, cluster size, etc.
            * kkrflex_file_paths: dict of absolute file paths for the kkrflex files
            * shapefun_path: absolute path of the shapefunction file in the host calculation (needed to construct shapefun_imp)
            * shapes: mapping array of atoms to shapes (<SHAPE> input)
        :note: shapefun_path is None if host_Greenfunction calculation was not full-potential
        :raises: 
            * InputValidationError, if inputdict does not contain 'host_Greenfunction'
            * InputValidationError, if host_Greenfunction_folder not of right type
            * UniquenessError, if host_Greenfunction_folder does not have exactly one parent
            * InputValidationError, if host_Greenfunction does not have an input node impurity_info
            * InputValidationError, if host_Greenfunction was not a KKRFLEX calculation
        """
        # get host_parent node and check consistency
        try:
            host_parent = inputdict.pop(self.get_linkname('host_Greenfunction_folder'))
        except KeyError:
            raise InputValidationError("No host_Greenfunction_folder specified for this calculation")
        # check host parent type
        if not isinstance(host_parent, RemoteData):
            raise InputValidationError("host_Greenfunction_folder not of type RemoteData")
        # extract parent calculation
        parent_calcs = host_parent.get_inputs(node_type=JobCalculation)
        n_parents = len(parent_calcs)
        if n_parents != 1:
            raise UniquenessError(
                    "Input RemoteData is child of {} "
                    "calculation{}, while it should have a single parent"
                    "".format(n_parents, "" if n_parents == 0 else "s"))
        else:
            parent_calc = parent_calcs[0]
            
        # extract impurity_info
        imp_info = parent_calc.get_inputs_dict().get('impurity_info', None)
        if imp_info is None:
            raise InputValidationError("host_Greenfunction calculation does not have an input node impurity_info")
            
        # check if host parent was KKRFLEX calculation
        hostfolderpath = parent_calc.out.retrieved.folder.abspath
        hostfolderpath = os.path.join(hostfolderpath, 'path')
        input_file = os.path.join(hostfolderpath, KkrCalculation()._DEFAULT_INPUT_FILE)
        params_host_calc = kkrparams(params_type='kkr') # initialize kkrparams instance to use read_keywords_from_inputcard
        params_host_calc.read_keywords_from_inputcard(inputcard=input_file)
        
        if 'RUNOPT' not in params_host_calc.get_dict().keys():
            host_ok = False
        elif 'KKRFLEX' not in params_host_calc.get_dict().get('RUNOPT', []):
            host_ok = False
        else:
            host_ok = True
            
        if not host_ok:
            raise InputValidationError("host_Greenfunction calculation was not a KKRFLEX run")
        
        # extract absolute paths of kkrflex_* files
        kkrflex_file_paths = {}
        for file in self._ALL_KKRFLEX_FILES:
            file_abspath = os.path.join(hostfolderpath, file)
            if os.path.exists(file_abspath):
                kkrflex_file_paths[file] = file_abspath
                
        # extract absolute path of host shapefun
        file_abspath = os.path.join(hostfolderpath, KkrCalculation()._SHAPEFUN)
        if os.path.exists(file_abspath):
            shapefun_path = file_abspath
        else:
            shapefun_path = None
            
        # extract shapes array from parameters read from inputcard
        shapes = params_host_calc.get_dict().get('<SHAPE>', None)
        if type(shapes)==int:
            shapes = [shapes]
            
        # extract input structure
        try:
            structure, voro_parent = VoronoiCalculation.find_parent_structure(parent_calc)
        except:
            structure, voro_parent = None, None
        if structure is None:
            raiseInputValidationError("No structure node found from host GF parent")
            
        return imp_info, kkrflex_file_paths, shapefun_path, shapes, parent_calc, params_host_calc, structure
        
        
    def _check_and_extract_input_nodes(self, inputdict):
        """
        Extract input nodes from inputdict and check consitency of input nodes
        :param inputdict: dict of inputnodes
        :returns: 
            * parameters (aiida_kkr.tools.kkr_params.kkrparams), optional: parameters of KKRimp that end up in config.cfg
            * code (KKRimpCodeNode): code of KKRimp on some machine
            * imp_info (ParameterDataNode): parameter node of the impurity information, extracted from host_parent_calc
            * kkrflex_file_paths (dict): dictionary of {filenames: absolute_path_to_file} for the kkrflex-files
            * shapfun_path (str): absolute path of the shapefunction of the host parent calculation
            * host_parent_calc (KkrCalculation): node of the parent host calculation where the kkrflex-files were created
            * impurity_potential (SinglefileData): single file data node containing the starting potential for the impurity calculation
            * parent_calc_folder (RemoteData): remote directory of a parent KKRimp calculation
        """
        # 1. extract parameters, optional (defaults extracted from host calculation)
        try:
            parameters = inputdict.pop(self.get_linkname('parameters'))
            if not isinstance(parameters, ParameterData):
                raise InputValidationError("parameters not of type ParameterData")
        except KeyError:
            self.logger.info("No parameters specified for this calculation, use defaults")
            parameters = None
        if parameters is not None: # convert to kkrparams instance
            parameters = kkrparams(params_type='kkrimp', **parameters.get_dict())
        # 2. extract code
        try:
            code = inputdict.pop(self.get_linkname('code'))
        except KeyError:
            raise InputValidationError("No code specified for this calculation")
        # 3. get hostfiles
        imp_info, kkrflex_file_paths, shapfun_path, shapes, host_parent_calc, params_host, structure = self._get_and_verify_hostfiles(inputdict)
        
        # 4. check impurity potential or parent calc input
        # imp potential
        try:
            impurity_potential = inputdict.pop(self.get_linkname('impurity_potential'))
            if not isinstance(impurity_potential, SinglefileData):
                raise InputValidationError("impurity_potential not of type SinglefileData")
            found_imp_pot = True
        except KeyError:
            impurity_potential = None
            found_imp_pot = False
        # parent calc folder
        try:
            parent_calc_folder = inputdict.pop(self.get_linkname('parent_calc_folder'))
            if not isinstance(parent_calc_folder, RemoteData):
                raise InputValidationError("parent_calc_folder not of type RemoteData")
            found_parent_calc = True
        except KeyError:
            parent_calc_folder = None
            found_parent_calc = False
        # consistency checks
        if not found_parent_calc and not found_imp_pot:
            raise InputValidationError("Neither impurity_potential nor parent_calc_folder specified for this calculation.\n"
                                       "Please provide either impurity_potential or parent_calc_folder.")
        elif found_parent_calc and found_imp_pot:
            raise InputValidationError("Both impurity_potential and parent_calc_folder specified for this calculation.\n"
                                       "Please provide one one, i.e. either impurity_potential or parent_calc_folder.")
        # 5. anything left that is unknown?
        if inputdict:
            raise ValidationError("Unknown inputs: {}".format(inputdict))
        # Done checking inputdict, returning ...
        return parameters, code, imp_info, kkrflex_file_paths, shapfun_path, shapes, host_parent_calc, params_host, impurity_potential, parent_calc_folder, structure


    def _extract_and_write_config(self, parent_calc_folder, params_host, parameters, tempfolder):
        """
        fill kkr params for KKRimp and write config file
        """
        # initialize kkrimp parameter set with default values
        params_kkrimp = kkrparams(params_type='kkrimp', NPAN_LOGPANELFAC=2, 
                                  RADIUS_MIN=-1, NCOLL=0, SPINORBIT=0, SCFSTEPS=1,
                                  IMIX=0, MIXFAC=0.05, ITDBRY=20, BRYMIX=0.05,
                                  QBOUND=10**-7, RUNFLAG=[], TESTFLAG=[], HFIELD=[0.0, 0],
                                  CALCFORCE=0, CALCJIJMAT=0, CALCORBITALMOMENT=0, ICST=2)
        
        # keys that are being overwritten from host calculation settings
        keys_overwrite = ['NSPIN', 'KVREL', 'XC', 'INS', 'ICST', 'RADIUS_LOGPANELS',
                          'NPAN_EQ', 'NPAN_LOG', 'NCHEB', 'QBOUND']
        for key in keys_overwrite:
            if key=='XC':
                key0 = 'KEXCOR'
            elif key=='RADIUS_LOGPANELS':
                key0 = 'R_LOG'
            elif key=='MIXFAC':
                key0 = 'STRMIX'
            else:
                key0 = key
            val = params_host.get_value(key0)
            if val is not None:
                params_kkrimp.set_value(key, val)
        # settings for SOC solver
        runopts = params_host.get_value('RUNOPT')
        if 'NEWSOSOL' in runopts:
            params_kkrimp.set_multiple_values(NCOLL=1, SPINORBIT=1, CALCORBITALMOMENT=1, TESTFLAG=['tmatnew'])
        else:
            params_kkrimp.set_multiple_values(NCOLL=0, SPINORBIT=0, CALCORBITALMOMENT=0, TESTFLAG=[])
        # special settings
        runopts = params_host.get_value('RUNOPT')
        if 'SIMULASA' in runopts or (params_kkrimp.get_value('NCOLL')>0 and params_kkrimp.get_value('INS')>0):
            params_kkrimp.set_value('RUNFLAG', ['SIMULASA'])
        else:
            params_kkrimp.set_value('RUNFLAG', [])
            
        # overwrite keys if found in parent_calc
        if parent_calc_folder is not None:
            params_parent = parent_calc_folder.get_inputs_dict().get('parameters', None)
        else:
            params_parent = None
        if params_parent is not None:
            params_parent = kkrparams(params_type='kkr', **params_parent.get_dict())
            for (key, val) in params_parent.get_set_values():
                self._check_key_setting_consistency(params_kkrimp, key, val)
                params_kkrimp.set_value(key, val)
        
        # overwrite from input parameters
        if parameters is not None:
            for (key, val) in parameters.get_set_values():
                self._check_key_setting_consistency(params_kkrimp, key, val)
                params_kkrimp.set_value(key, val)
                
        # write config.cfg
        config_filename = tempfolder.get_abs_path(self._CONFIG)
        params_kkrimp.fill_keywords_to_inputfile(output=config_filename)
    

    def _change_atominfo(self, imp_info, kkrflex_file_paths, tempfolder):
        """
        change kkrflex_atominfo to match impurity case
        """
        # read in atominfo file as it is written out
        with open(kkrflex_file_paths.get(KkrCalculation()._KKRFLEX_ATOMINFO)) as file:
            atominfo = file.readlines()
            
        #TODO implement logic to extract this info from imp_info
        replace_zatom_imp = []
        
        # read scoef for comparison with Rimp_rel
        scoef = []
        with open(tempfolder.get_abs_path(KkrCalculation()._SCOEF), 'r') as file:
            Nscoef = int(file.readline().split()[0])
            for iline in range(Nscoef):
                tmpline = file.readline().split()
                scoef.append([float(i) for i in tmpline[:3]])
        scoef = array(scoef)
        
        # find replaceZimp list from Zimp and Rimp_rel
        imp_info_dict = imp_info.get_dict()
        Zimp_list = imp_info_dict.get('Zimp')
        Rimp_rel_list = imp_info_dict.get('Rimp_rel', [[0,0,0]])
        for iatom in range(len(Zimp_list)):
            rtmp = Rimp_rel_list[iatom]
            diff = sqrt(sum((rtmp-scoef)**2, axis=1))
            Zimp = Zimp_list[iatom]
            ipos_replace = where(diff==diff.min())[0][0]
            replace_zatom_imp.append([ipos_replace, Zimp])
        
        for (iatom, zimp) in replace_zatom_imp:
            tmp = atominfo[iatom+4].split()
            x, y, z = float(tmp[0]), float(tmp[1]), float(tmp[2])
            zatom = float(tmp[3])
            virt, remove, lmax = int(tmp[4]), int(tmp[5]), int(tmp[6])
            zatom = zimp
            tmp = ' %24.16f %24.16f %24.16f %5.2f %4i %4i %4i\n'%(x, y, z, zatom, virt, remove, lmax)
            atominfo[iatom+4] = tmp
            
        # write atominfo file
        atominfo_path = tempfolder.get_abs_path(self._KKRFLEX_ATOMINFO)
        with open(atominfo_path, 'w') as file:
            file.writelines(atominfo)
    

    def _get_pot_and_shape(self, imp_info, shapefun_path, shapes, impurity_potential, parent_calc_folder, tempfolder, structure):
        """
        write shapefun from impurity info and host shapefun and copy imp. potential
        """

        scoef_filename = os.path.join(tempfolder.get_abs_path(''), KkrCalculation()._SCOEF)
        imp_info_dict = imp_info.get_dict()
        Rcut = imp_info_dict.get('Rcut', None)
        hcut = imp_info_dict.get('hcut', -1.)
        cylinder_orient = imp_info_dict.get('cylinder_orient', [0., 0., 1.])
        ilayer_center = imp_info_dict.get('ilayer_center', 0)
        make_scoef(structure, Rcut, scoef_filename, hcut, cylinder_orient, ilayer_center)
        
        # create impurity shapefun
        shapefun_new_path = tempfolder.get_abs_path(self._SHAPEFUN)
        modify_potential().shapefun_from_scoef(scoef_filename, shapefun_path, shapes, shapefun_new_path)
            
        # find path to input potential
        if impurity_potential is not None:
            potfile = impurity_potential.get_file_abs_path()
        elif parent_calc_folder is not None:
            self.logger.info('parent_calc_folder {} {}'.format(parent_calc_folder, parent_calc_folder.get_inputs_dict()))
            retrieved = parent_calc_folder.get_inputs(node_type=JobCalculation)[0].get_outputs_dict().get('retrieved', None)
            self.logger.info('potfile {} {}'.format(retrieved, self._OUT_POTENTIAL))
            potfile = retrieved.get_abs_path(self._OUT_POTENTIAL)
        else:
            raise InputValidationError('ERROR in _get_pot_and_shape: neither impurity potential nor parent_calc_folder given!')
            
        # return path of input potential (added to copy_list)
        return potfile
        
    
    def _check_key_setting_consistency(self, params_kkrimp, key, val):
        """
        Check if key/value pair that is supposed to be set is not in conflict with previous settings of parameters in params_kkrimp
        """
        param_ok = True
        
        #TODO implement checks
        
        if not param_ok:
            raise ValueError('Trying to set key "{}" with value "{}" which is in conflict to previous settings!'.format(key, val))
예제 #15
0
 def _get_and_verify_hostfiles(self, inputdict):
     """
     Check inputdict for host_Greenfunction_folder and extract impurity_info, paths to kkrflex-files and path of shapefun file
     
     :param inputdict: input dictionary containing all input nodes to KkrimpCalculation
     :returns: 
         * imp_info: ParameterData node containing impurity information like position, Z_imp, cluster size, etc.
         * kkrflex_file_paths: dict of absolute file paths for the kkrflex files
         * shapefun_path: absolute path of the shapefunction file in the host calculation (needed to construct shapefun_imp)
         * shapes: mapping array of atoms to shapes (<SHAPE> input)
     :note: shapefun_path is None if host_Greenfunction calculation was not full-potential
     :raises: 
         * InputValidationError, if inputdict does not contain 'host_Greenfunction'
         * InputValidationError, if host_Greenfunction_folder not of right type
         * UniquenessError, if host_Greenfunction_folder does not have exactly one parent
         * InputValidationError, if host_Greenfunction does not have an input node impurity_info
         * InputValidationError, if host_Greenfunction was not a KKRFLEX calculation
     """
     # get host_parent node and check consistency
     try:
         host_parent = inputdict.pop(self.get_linkname('host_Greenfunction_folder'))
     except KeyError:
         raise InputValidationError("No host_Greenfunction_folder specified for this calculation")
     # check host parent type
     if not isinstance(host_parent, RemoteData):
         raise InputValidationError("host_Greenfunction_folder not of type RemoteData")
     # extract parent calculation
     parent_calcs = host_parent.get_inputs(node_type=JobCalculation)
     n_parents = len(parent_calcs)
     if n_parents != 1:
         raise UniquenessError(
                 "Input RemoteData is child of {} "
                 "calculation{}, while it should have a single parent"
                 "".format(n_parents, "" if n_parents == 0 else "s"))
     else:
         parent_calc = parent_calcs[0]
         
     # extract impurity_info
     imp_info = parent_calc.get_inputs_dict().get('impurity_info', None)
     if imp_info is None:
         raise InputValidationError("host_Greenfunction calculation does not have an input node impurity_info")
         
     # check if host parent was KKRFLEX calculation
     hostfolderpath = parent_calc.out.retrieved.folder.abspath
     hostfolderpath = os.path.join(hostfolderpath, 'path')
     input_file = os.path.join(hostfolderpath, KkrCalculation()._DEFAULT_INPUT_FILE)
     params_host_calc = kkrparams(params_type='kkr') # initialize kkrparams instance to use read_keywords_from_inputcard
     params_host_calc.read_keywords_from_inputcard(inputcard=input_file)
     
     if 'RUNOPT' not in params_host_calc.get_dict().keys():
         host_ok = False
     elif 'KKRFLEX' not in params_host_calc.get_dict().get('RUNOPT', []):
         host_ok = False
     else:
         host_ok = True
         
     if not host_ok:
         raise InputValidationError("host_Greenfunction calculation was not a KKRFLEX run")
     
     # extract absolute paths of kkrflex_* files
     kkrflex_file_paths = {}
     for file in self._ALL_KKRFLEX_FILES:
         file_abspath = os.path.join(hostfolderpath, file)
         if os.path.exists(file_abspath):
             kkrflex_file_paths[file] = file_abspath
             
     # extract absolute path of host shapefun
     file_abspath = os.path.join(hostfolderpath, KkrCalculation()._SHAPEFUN)
     if os.path.exists(file_abspath):
         shapefun_path = file_abspath
     else:
         shapefun_path = None
         
     # extract shapes array from parameters read from inputcard
     shapes = params_host_calc.get_dict().get('<SHAPE>', None)
     if type(shapes)==int:
         shapes = [shapes]
         
     # extract input structure
     try:
         structure, voro_parent = VoronoiCalculation.find_parent_structure(parent_calc)
     except:
         structure, voro_parent = None, None
     if structure is None:
         raiseInputValidationError("No structure node found from host GF parent")
         
     return imp_info, kkrflex_file_paths, shapefun_path, shapes, parent_calc, params_host_calc, structure