Exemplo n.º 1
0
def validate_kpoint_mesh(callback_kwargs, ctx, param, value):
    """
    Command line option validator for a kpoints mesh tuple. The value should be a tuple
    of three positive integers out of which a KpointsData object will be created with
    a mesh equal to the tuple.

    :param callback_kwargs: an optional dictionary with arguments for internal use in the validator
    :param ctx: internal context of the click.command
    :param param: the click Parameter, i.e. either the Option or Argument to which the validator is hooked up
    :param value: a tuple of three positive integers
    :returns: a KpointsData instance
    """
    from aiida.orm.data.array.kpoints import KpointsData

    if any([type(i) != int
            for i in value]) or any([int(i) <= 0 for i in value]):
        raise click.BadParameter(
            'all values of the tuple should be positive greater than zero integers'
        )

    try:
        kpoints = KpointsData()
        kpoints.set_kpoints_mesh(value)
    except ValueError as exception:
        raise click.BadParameter(
            "failed to create a KpointsData mesh out of {}\n{}".format(
                value, exception))

    return kpoints
Exemplo n.º 2
0
 def setup_kpoints(self):
     """
     Define the k-point mesh for the Siesta calculation.
     """
     self.report('Running setup_kpoints')
     kpoints_mesh = KpointsData()
     kpmesh=self.ctx.protocol['kpoints_mesh']
     kpoints_mesh.set_kpoints_mesh([kpmesh,kpmesh,kpmesh])
     
     self.ctx.kpoints_mesh = kpoints_mesh
Exemplo n.º 3
0
    def sub_create_bands_data(cls, user=None):
        from aiida.orm.data.array.kpoints import KpointsData
        from aiida.orm import JobCalculation
        from aiida.orm.data.structure import StructureData
        from aiida.common.links import LinkType
        from aiida.orm.data.array.bands import BandsData
        import numpy

        s = StructureData(cell=((2., 0., 0.), (0., 2., 0.), (0., 0., 2.)))
        s.append_atom(position=(0., 0., 0.),
                      symbols=['Ba', 'Ti'],
                      weights=(1., 0.),
                      name='mytype')
        if user is not None:
            s.dbnode.user = user._dbuser
        s.store()

        c = JobCalculation(computer=cls.computer,
                           resources={
                               'num_machines': 1,
                               'num_mpiprocs_per_machine': 1
                           })
        if user is not None:
            c.dbnode.user = user._dbuser
        c.store()
        c.add_link_from(s, "S1", LinkType.INPUT)
        c._set_state(calc_states.RETRIEVING)

        # define a cell
        alat = 4.
        cell = numpy.array([
            [alat, 0., 0.],
            [0., alat, 0.],
            [0., 0., alat],
        ])

        k = KpointsData()
        k.set_cell(cell)
        k.set_kpoints_path()
        if user is not None:
            k.dbnode.user = user._dbuser
        k.store()

        b = BandsData()
        b.set_kpointsdata(k)
        input_bands = numpy.array(
            [numpy.ones(4) * i for i in range(k.get_kpoints().shape[0])])
        b.set_bands(input_bands, units='eV')
        if user is not None:
            b.dbnode.user = user._dbuser
        b.store()

        b.add_link_from(c, link_type=LinkType.CREATE)

        return b
Exemplo n.º 4
0
def execute(args):
    """
    The main execution of the script, which will run some preliminary checks on the command
    line arguments before passing them to the workchain and running it
    """
    try:
        code = Code.get_from_string(args.codename)
    except NotExistent as exception:
        print "Execution failed: could not retrieve the code '{}'".format(args.codename)
        print "Exception report: {}".format(exception)
        return

    try:
        parent_calc = load_node(args.parent_calc)
    except NotExistent as exception:
        print "Execution failed: failed to load the node for the given parent calculation '{}'".format(args.parent_calc)
        print "Exception report: {}".format(exception)
        return

    if not isinstance(parent_calc, PwCalculation):
        print "The provided parent calculation {} is not of type PwCalculation, aborting...".format(args.parent_calc)
        return

    qpoints = KpointsData()
    qpoints.set_kpoints_mesh(args.qpoints)

    parameters = {
        'INPUTPH': {
            'tr2_ph': 1e-10,
        }
    }
    settings = {}
    options  = {
        'resources': {
            'num_machines': 1
        },
        'max_wallclock_seconds': args.max_wallclock_seconds,
    }

    run(
        PhBaseWorkChain,
        code=code,
        parent_calc=parent_calc,
        qpoints=qpoints,
        parameters=ParameterData(dict=parameters),
        settings=ParameterData(dict=settings),
        options=ParameterData(dict=options),
        max_iterations=Int(args.max_iterations)
    )
    def submit_jobs(self):
        print("structure PK: %i" % self.inputs.structure.pk)

        grp, created = Group.get_or_create(name=self.inputs.group)
        grp.add_nodes([self.calc])
        print("stress tensor PK: %i" % self.calc.pk)

        # get calculation class
        C = CalculationFactory(self.inputs.code.get_input_plugin_name())

        Proc = C.process()

        num_points = 5

        # volume scales from 0.94 to 1.06, alat scales as pow(1/3)
        scales = numpy.linspace(0.94**(1 / 3.0), 1.06**(1 / 3.0),
                                num_points).tolist()

        calcs = {}

        for scale in scales:
            print("scale = %f" % scale)
            # scaled structure
            new_structure = scaled_structure(self.inputs.structure,
                                             Float(scale))
            # basic parameters of the calculation
            params = calculation_helpers.create_calculation_parameters(
                self.inputs.code, str(self.inputs.partition),
                int(self.inputs.ranks_per_node), int(self.inputs.ranks_kp),
                int(self.inputs.ranks_diag))

            inputs = Proc.get_inputs_template()
            inputs.code = self.inputs.code

            inputs._options.resources = params['calculation_resources']
            inputs._options.max_wallclock_seconds = 20 * 60
            inputs._options.custom_scheduler_commands = params[
                'custom_scheduler_commands']
            inputs._options.environment_variables = params[
                'environment_variables']
            inputs._options.mpirun_extra_params = params['mpirun_extra_params']

            inputs.structure = new_structure
            inputs.kpoints = KpointsData()
            inputs.kpoints.set_kpoints_mesh(self.inputs.kmesh,
                                            offset=(0.0, 0.0, 0.0))

            inputs.parameters = params['calculation_parameters']
            inputs.settings = params['calculation_settings']

            if self.inputs.code.get_input_plugin_name(
            ) == 'quantumespresso.pw':
                inputs.pseudo = get_pseudos(new_structure,
                                            self.inputs.atomic_files)

            if self.inputs.code.get_input_plugin_name() == 'exciting.exciting':
                inputs.lapwbasis = get_lapwbasis(new_structure,
                                                 self.inputs.atomic_files)

            future = submit(Proc, **inputs)
def execute(args):
    """
    The main execution of the script, which will run some preliminary checks on the command
    line arguments before passing them to the workchain and running it
    """
    try:
        code = Code.get_from_string(args.codename)
    except NotExistent as exception:
        print "Execution failed: could not retrieve the code '{}'".format(args.codename)
        print "Exception report: {}".format(exception)
        return

    try:
        structure = load_node(args.structure)
    except NotExistent as exception:
        print "Execution failed: failed to load the node for the given structure pk '{}'".format(args.structure)
        print "Exception report: {}".format(exception)
        return

    if not isinstance(structure, StructureData):
        print "The provided pk {} for the structure does not correspond to StructureData, aborting...".format(args.parent_calc)
        return

    kpoints = KpointsData()
    kpoints.set_kpoints_mesh(args.kpoints)

    parameters = load_property_json('parameters.json')
    basis = load_property_json('basis.json')
    settings = load_property_json('settings.json')
    options = load_property_json('options.json')

    options['max_wallclock_seconds'] = args.max_wallclock_seconds

    run(
        SiestaWorkChain,
        code=code,
        structure=structure,
        pseudo_family=Str(args.pseudo_family),
        kpoints=kpoints,
        parameters=ParameterData(dict=parameters),
        settings=ParameterData(dict=settings),
        options=ParameterData(dict=options),
        basis=ParameterData(dict=basis),
        max_iterations=Int(args.max_iterations),
    )
    def setup_kpoints(self):
        """
        Define the k-point mesh for the relax and scf calculations. Also get the k-point path for
        the bands calculation for the initial input structure from SeeKpath
        """
        kpoints_mesh = KpointsData()
        kpoints_mesh.set_cell_from_structure(self.inputs.structure)
        kpoints_mesh.set_kpoints_mesh_from_density(
            distance=self.ctx.protocol['kpoints_mesh_density'],
            offset=self.ctx.protocol['kpoints_mesh_offset'])

        self.ctx.kpoints_mesh = kpoints_mesh
Exemplo n.º 8
0
    def _get_kpoints(self, nx, use_symmetry=True):
        nx = max(1, nx)

        kpoints = KpointsData()
        if use_symmetry:
            kpoints.set_kpoints_mesh([nx, 1, 1], offset=[0.0, 0.0, 0.0])
        else:
            # list kpoints explicitly
            points = [[r, 0.0, 0.0] for r in np.linspace(0, 0.5, nx)]
            kpoints.set_kpoints(points)

        return kpoints
Exemplo n.º 9
0
    def setup_kpoints(self):
        """
        Define the k-point mesh for the relax and scf calculations.
        """

        kpoints_mesh = KpointsData()
        kpoints_mesh.set_cell_from_structure(self.ctx.structure_initial_primitive)
        kpoints_mesh.set_kpoints_mesh_from_density(
            distance=self.ctx.protocol['kpoints_mesh_density'],
            offset=self.ctx.protocol['kpoints_mesh_offset']
        )
        
        self.ctx.kpoints_mesh = kpoints_mesh
Exemplo n.º 10
0
        def connect_structure_bands(structure):
            alat = 4.
            cell = np.array([
                [alat, 0., 0.],
                [0., alat, 0.],
                [0., 0., alat],
            ])

            k = KpointsData()
            k.set_cell(cell)
            k.set_kpoints_path([('G', 'M', 2)])

            b = BandsData()
            b.set_kpointsdata(k)
            b.set_bands([[1.0, 2.0], [3.0, 4.0]])

            k.store()
            b.store()

            return b
Exemplo n.º 11
0
def _legacy_get_explicit_kpoints_path(structure, **kwargs):
    """
    Call the get_explicit_kpoints_path of the legacy implementation

    :param structure: a StructureData node
    :param float kpoint_distance: parameter controlling the distance between kpoints. Distance is
        given in crystal coordinates, i.e. the distance is computed in the space of b1, b2, b3.
        The distance set will be the closest possible to this value, compatible with the requirement
        of putting equispaced points between two special points (since extrema are included).
    :param bool cartesian: if set to true, reads the coordinates eventually passed in value as cartesian coordinates
    :param float epsilon_length: threshold on lengths comparison, used to get the bravais lattice info
    :param float epsilon_angle: threshold on angles comparison, used to get the bravais lattice info
    """
    args_recognized = [
        'value', 'kpoint_distance', 'cartesian', 'epsilon_length',
        'epsilon_angle'
    ]
    args_unknown = set(kwargs).difference(args_recognized)

    if args_unknown:
        raise ValueError("unknown arguments {}".format(args_unknown))

    point_coords, path, bravais_info, explicit_kpoints, labels = legacy.get_explicit_kpoints_path(
        cell=structure.cell, pbc=structure.pbc, **kwargs)

    kpoints = KpointsData()
    kpoints.set_cell(structure.cell)
    kpoints.set_kpoints(explicit_kpoints)
    kpoints.labels = labels

    parameters = {
        'bravais_info': bravais_info,
        'point_coords': point_coords,
        'path': path,
    }

    return {
        'parameters': ParameterData(dict=parameters),
        'explicit_kpoints': kpoints
    }
Exemplo n.º 12
0
def create_kpoints_from_distance(structure, distance, force_parity):
    """
    Generate a uniformly spaced kpoint mesh for a given structure where the spacing between kpoints in reciprocal
    space is guaranteed to be at least the defined distance.

    :param structure: the StructureData to which the mesh should apply
    :param distance: a Float with the desired distance between kpoints in reciprocal space
    :param force_parity: a Bool to specify whether the generated mesh should maintain parity
    :returns: a KpointsData with the generated mesh
    """
    from aiida.orm.data.array.kpoints import KpointsData

    kpoints = KpointsData()
    kpoints.set_cell_from_structure(structure)
    kpoints.set_kpoints_mesh_from_density(distance.value,
                                          force_parity=force_parity.value)

    return kpoints
Exemplo n.º 13
0
    def run_seekpath(self):
        """
        Run the relaxed structure through SeeKPath to get the new primitive structure, just in case
        the symmetry of the cell changed in the cell relaxation step
        """
        if 'workchain_relax' not in self.ctx:
            structure = self.inputs.structure
        else:
            try:
                structure = self.ctx.workchain_relax.out.output_structure
            except:
                self.abort_nowait(
                    'the relax workchain did not output an output_structure node'
                )
                return

        seekpath_parameters = ParameterData(
            dict={
                'reference_distance': self.inputs.kpoints_distance_bands.value
            })

        result = seekpath_structure_analysis(structure, seekpath_parameters)
        self.ctx.structure = result['primitive_structure']

        # Construct a new kpoint mesh for the scf calculation on the current primitive structure
        kpoints_mesh = KpointsData()
        kpoints_mesh.set_cell_from_structure(self.ctx.structure)
        kpoints_mesh.set_kpoints_mesh_from_density(
            self.inputs.kpoints_distance.value)

        # Save the kpoints objects for the scf and bands calculation in the context
        self.ctx.kpoints_mesh = kpoints_mesh
        self.ctx.kpoints_path = result['explicit_kpoints']

        self.out('primitive_structure', result['primitive_structure'])
        self.out('seekpath_parameters', result['parameters'])
Exemplo n.º 14
0
def execute(args):
    """
    The main execution of the script, which will run some preliminary checks on the command
    line arguments before passing them to the workchain and running it
    """
    try:
        code = Code.get_from_string(args.codename)
    except NotExistent as exception:
        print "Execution failed: could not retrieve the code '{}'".format(args.codename)
        print "Exception report: {}".format(exception)
        return

    try:
        structure = load_node(args.structure)
    except:
        #
        # Slightly distorted structure
        #
        alat = 5.430 # angstrom
        cell = [[0.5*alat, 0.5*alat, 0.,],
                [0., 0.5*alat, 0.5*alat,],
                [0.5*alat, 0., 0.5*alat,],
        ]

        # Si
        # This was originally given in the "ScaledCartesian" format
        #
        structure = StructureData(cell=cell)
        structure.append_atom(position=(0.000*alat,0.000*alat,0.000*alat),symbols=['Si'])
        structure.append_atom(position=(0.250*alat,0.245*alat,0.250*alat),symbols=['Si'])
        
        #print "Execution failed: failed to load the node for the given structure pk '{}'".format(args.structure)
        #print "Exception report: {}".format(exception)
        #return

    if not isinstance(structure, StructureData):
        print "The provided pk {} for the structure does not correspond to StructureData, aborting...".format(args.parent_calc)
        return

    kpoints = KpointsData()
    kpoints.set_kpoints_mesh(args.kpoints)
    bandskpoints = KpointsData()

    bandskpoints.set_cell(structure.cell, structure.pbc)
    bandskpoints.set_kpoints_path(kpoint_distance = 0.05)


    parameters = {
                'xc-functional': 'LDA',
                'xc-authors': 'CA',
                'spinpolarized': False,
                'meshcutoff': '150.0 Ry',
                'max-scfiterations': 50,
                'dm-numberpulay': 4,
                'dm-mixingweight': 0.3,
                'dm-tolerance': 1.e-4,
                'Solution-method': 'diagon',
                'electronic-temperature': '25 meV',
                'md-typeofrun': 'cg',
                'md-numcgsteps': 10,
                'md-maxcgdispl': '0.1 Ang',
                'md-maxforcetol': '0.04 eV/Ang'
    }

    # default basis
    basis = {
        'pao-energy-shift': '100 meV',
        '%block pao-basis-sizes': """
        Si DZP                    """,
    }
    
    settings = {}
    options  = {
        'resources': {
            'num_machines': 1
        },
        'max_wallclock_seconds': args.max_wallclock_seconds,
    }

    run(
        SiestaBaseWorkChain,
        code=code,
        structure=structure,
        pseudo_family=Str(args.pseudo_family),
        kpoints=kpoints,
        bandskpoints=bandskpoints,
        parameters=ParameterData(dict=parameters),
        settings=ParameterData(dict=settings),
        options=ParameterData(dict=options),
        basis=ParameterData(dict=basis),
        max_iterations=Int(args.max_iterations),
    )
Exemplo n.º 15
0
alat=5.4
alat2=alat/2
alat3=alat2/2

from aiida.orm.data.array.kpoints import KpointsData
kpoints = KpointsData()
kpoints_mesh = 2
kpoints.set_kpoints_mesh([kpoints_mesh,kpoints_mesh,kpoints_mesh])

StructureData = DataFactory("structure")
the_cell = [[alat/2,alat/2,0.],[alat/2,0.,alat/2],[0.,alat/2,alat/2]]
structure = StructureData(cell=the_cell)
structure.cell
structure.append_atom(position=(alat/4.,alat/4.,alat/4.),symbols="Si")
structure.sites

from ase.lattice.spacegroup import crystal
ase_structure = crystal('Si', [(0,0,0)], spacegroup=227,
cellpar=[alat, alat, alat, 90, 90, 90],primitive_cell=True)
structure=StructureData(ase=ase_structure)
structure.store()

nameCode='pw@local-seb'

code=Code.get_from_string(nameCode)
calc=code.new_calc()
calc.label="PW test"
calc.description="First calculus on BaTiO3"
calc.set_resources({"num_machines": 1})
calc.set_max_wallclock_seconds(30*60)
Exemplo n.º 16
0
def get_explicit_kpoints_path(structure, parameters):
    """
    Return the kpoint path for band structure (in scaled and absolute 
    coordinates), given a crystal structure,
    using the paths proposed in the various publications (see description
    of the 'recipe' input parameter). The parameters are the same
    as get get_explicit_k_path in __init__, but here all structures are
    input and returned as AiiDA structures rather than tuples, and similarly
    k-points-related information as a AiiDA KpointsData class.

    :param structure: The AiiDA StructureData for which we want to obtain
        the suggested path. 

    :param parameters: A dictionary whose key-value pairs are passed as
        additional kwargs to the ``seekpath.get_explicit_k_path`` function.

    :return: A dictionary with four nodes:

        - ``explicit_kpoints``: a KpointsData with the (explicit) kpoints
          (with labels set).

        - ``parameters``: a ParameterData, whose content is
          the same dictionary as returned by the ``seekpath.get_explicit_k_path`` function
          (see `seekpath documentation <https://seekpath.readthedocs.io/>`_),
          except that:

          - ``conv_lattice``, ``conv_positions``, ``conv_types``
            are removed and replaced by the ``conv_structure`` output node

          - ``primitive_lattice``, ``primitive_positions``, ``primitive_types``
            are removed and replaced by the `primitive_structure` output node

          - ``reciprocal_primitive_lattice``, ``explicit_kpoints_abs``,  
            ``explicit_kpoints_rel`` and ``explicit_kpoints_labels`` are removed
            and replaced by the ``explicit_kpoints`` output node

        - ``primitive_structure``: A StructureData with the primitive structure

        - ``conv_structure``: A StructureData with the primitive structure
    """
    check_seekpath_is_installed()
    import seekpath

    structure_tuple, kind_info, kinds = structure_to_spglib_tuple(structure)

    result = {}
    rawdict = seekpath.get_explicit_k_path(structure=structure_tuple,
                                           **parameters)

    # Replace primitive structure with AiiDA StructureData
    primitive_lattice = rawdict.pop('primitive_lattice')
    primitive_positions = rawdict.pop('primitive_positions')
    primitive_types = rawdict.pop('primitive_types')
    primitive_tuple = (primitive_lattice, primitive_positions, primitive_types)
    primitive_structure = spglib_tuple_to_structure(primitive_tuple, kind_info,
                                                    kinds)

    # Replace conv structure with AiiDA StructureData
    conv_lattice = rawdict.pop('conv_lattice')
    conv_positions = rawdict.pop('conv_positions')
    conv_types = rawdict.pop('conv_types')
    conv_tuple = (conv_lattice, conv_positions, conv_types)
    conv_structure = spglib_tuple_to_structure(conv_tuple, kind_info, kinds)

    # Remove reciprocal_primitive_lattice, recalculated by kpoints class
    rawdict.pop('reciprocal_primitive_lattice')
    kpoints_abs = rawdict.pop('explicit_kpoints_abs')
    kpoints_rel = rawdict.pop('explicit_kpoints_rel')
    kpoints_labels = rawdict.pop('explicit_kpoints_labels')

    # set_kpoints expects labels like [[0,'X'],[34,'L'],...], so generate it here skipping empty labels
    labels = [[idx, label] for idx, label in enumerate(kpoints_labels)
              if label]
    kpoints = KpointsData()
    kpoints.set_cell_from_structure(primitive_structure)
    kpoints.set_kpoints(kpoints_abs, cartesian=True, labels=labels)

    result['parameters'] = ParameterData(dict=rawdict)
    result['explicit_kpoints'] = kpoints
    result['primitive_structure'] = primitive_structure
    result['conv_structure'] = conv_structure

    return result
Exemplo n.º 17
0
    def parse_with_retrieved(self, retrieved):
        """
        Parse the output nodes for a PwCalculations from a dictionary of retrieved nodes.
        Two nodes that are expected are the default 'retrieved' FolderData node which will
        store the retrieved files permanently in the repository. The second required node
        is the unstored FolderData node with the temporary retrieved files, which should
        be passed under the key 'retrieved_temporary_folder_key' of the Parser class.

        :param retrieved: a dictionary of retrieved nodes
        """
        import os

        successful = True

        # Load the input dictionary
        parameters = self._calc.inp.parameters.get_dict()

        # Look for optional settings input node and potential 'parser_options' dictionary within it
        try:
            settings = self._calc.inp.settings.get_dict()
            parser_opts = settings[self.get_parser_settings_key()]
        except (AttributeError, KeyError):
            settings = {}
            parser_opts = {}

        # Check that the retrieved folder is there
        try:
            out_folder = retrieved[self._calc._get_linkname_retrieved()]
        except KeyError:
            self.logger.error("No retrieved folder found")
            return False, ()

        # Verify that the retrieved_temporary_folder is within the arguments if temporary files were specified
        if self._calc._get_retrieve_temporary_list():
            try:
                temporary_folder = retrieved[
                    self.retrieved_temporary_folder_key]
                dir_with_bands = temporary_folder.get_abs_path('.')
            except KeyError:
                self.logger.error(
                    'the {} was not passed as an argument'.format(
                        self.retrieved_temporary_folder_key))
                return False, ()
        else:
            dir_with_bands = None

        list_of_files = out_folder.get_folder_list()

        # The stdout is required for parsing
        if self._calc._OUTPUT_FILE_NAME not in list_of_files:
            self.logger.error(
                "The standard output file '{}' was not found but is required".
                format(self._calc._OUTPUT_FILE_NAME))
            return False, ()

        # The xml file is required for parsing
        if self._calc._DATAFILE_XML_BASENAME not in list_of_files:
            self.logger.error(
                "The xml output file '{}' was not found but is required".
                format(self._calc._DATAFILE_XML_BASENAME))
            successful = False
            xml_file = None
        else:
            xml_file = os.path.join(out_folder.get_abs_path('.'),
                                    self._calc._DATAFILE_XML_BASENAME)

        out_file = os.path.join(out_folder.get_abs_path('.'),
                                self._calc._OUTPUT_FILE_NAME)

        # Call the raw parsing function
        parsing_args = [
            out_file, parameters, parser_opts, xml_file, dir_with_bands
        ]
        out_dict, trajectory_data, structure_data, bands_data, raw_successful = parse_raw_output(
            *parsing_args)

        # If calculation was not considered failed already, use the new value
        successful = raw_successful if successful else successful

        # If the parser option 'all_symmetries' is not set to True, we reduce the raw parsed symmetries to safe space
        all_symmetries = parser_opts.get('all_symmetries', False)

        if not all_symmetries:

            # In the standard output, each symmetry operation print two rotation matrices:
            #
            # * S_cryst^T: matrix in crystal coordinates, transposed
            # * S_cart: matrix in cartesian coordinates,
            #
            # The XML files only print one matrix:
            #
            # * S_cryst: matrix in crystal coordinates
            #
            # The raw parsed symmetry information from the XML is large and will load the database heavily if stored as
            # is for each calculation. Instead, we will map these dictionaries onto a static dictionary of rotation
            # matrices generated by the _get_qe_symmetry_list static method. This dictionary will return the rotation
            # matrices in cartesian coordinates, i.e. S_cart. In order to compare the raw matrices from the XML to these
            # static matrices we have to convert S_cryst into S_cart. We derive here how that is done:
            #
            #   S_cryst * v_cryst = v_cryst'
            #
            # where v_cryst' is the rotated vector v_cryst under S_cryst
            # We define `cell` where cell vectors are rows. Converting a vector from crystal to cartesian
            # coordinates is defined as:
            #
            #   cell^T * v_cryst = v_cart
            #
            # The inverse of this operation is defined as
            #
            #   v_cryst = cell^Tinv * v_cart
            #
            # Replacing the last equation into the first we find:
            #
            #   S_cryst * cell^Tinv * v_cart = cell^Tinv * v_cart'
            #
            # Multiply on the left with cell^T gives:
            #
            #   cell^T * S_cryst * cell^Tinv * v_cart = v_cart'
            #
            # which can be rewritten as:
            #
            #   S_cart * v_cart = v_cart'
            #
            # where:
            #
            #   S_cart = cell^T * S_cryst * cell^Tinv
            #
            # We compute here the transpose and its inverse of the structure cell basis, which is needed to transform
            # the parsed rotation matrices, which are in crystal coordinates, to cartesian coordinates, which are the
            # matrices that are returned by the _get_qe_symmetry_list staticmethod
            cell = structure_data['cell']['lattice_vectors']
            cell_T = numpy.transpose(cell)
            cell_Tinv = numpy.linalg.inv(cell_T)

            try:
                if 'symmetries' in out_dict.keys():
                    old_symmetries = out_dict['symmetries']
                    new_symmetries = []
                    for this_sym in old_symmetries:
                        name = this_sym['name'].strip()
                        for i, this in enumerate(self._possible_symmetries):
                            # Since we do an exact comparison we strip the string name from whitespace
                            # and as soon as it is matched, we break to prevent it from matching another
                            if name == this['name'].strip():
                                index = i
                                break
                        else:
                            index = None
                            self.logger.error(
                                'Symmetry {} not found'.format(name))

                        new_dict = {}
                        if index is not None:
                            # The raw parsed rotation matrix is in crystal coordinates, whereas the mapped rotation
                            # in self._possible_symmetries is in cartesian coordinates. To allow them to be compared
                            # to make sure we matched the correct rotation symmetry, we first convert the parsed matrix
                            # to cartesian coordinates. For explanation of the method, see comment above.
                            rotation_cryst = this_sym['rotation']
                            rotation_cart_new = self._possible_symmetries[
                                index]['matrix']
                            rotation_cart_old = numpy.dot(
                                cell_T, numpy.dot(rotation_cryst, cell_Tinv))

                            inversion = self._possible_symmetries[index][
                                'inversion']
                            if not are_matrices_equal(
                                    rotation_cart_old,
                                    rotation_cart_new,
                                    swap_sign_matrix_b=inversion):
                                self.logger.error(
                                    'Mapped rotation matrix {} does not match the original rotation {}'
                                    .format(rotation_cart_new,
                                            rotation_cart_old))
                                new_dict['all_symmetries'] = this_sym
                            else:
                                # Note: here I lose the information about equivalent ions and fractional_translation.
                                new_dict['t_rev'] = this_sym['t_rev']
                                new_dict['symmetry_number'] = index
                        else:
                            new_dict['all_symmetries'] = this_sym

                        new_symmetries.append(new_dict)

                    out_dict[
                        'symmetries'] = new_symmetries  # and overwrite the old one
            except KeyError:  # no symmetries were parsed (failed case, likely)
                self.logger.error("No symmetries were found in output")

        new_nodes_list = []

        # I eventually save the new structure. structure_data is unnecessary after this
        in_struc = self._calc.get_inputs_dict()['structure']
        type_calc = parameters['CONTROL']['calculation']
        struc = in_struc
        if type_calc in ['relax', 'vc-relax', 'md', 'vc-md']:
            if 'cell' in structure_data.keys():
                struc = convert_qe2aiida_structure(structure_data,
                                                   input_structure=in_struc)
                new_nodes_list.append(
                    (self.get_linkname_outstructure(), struc))

        k_points_list = trajectory_data.pop('k_points', None)
        k_points_weights_list = trajectory_data.pop('k_points_weights', None)

        if k_points_list is not None:

            # Build the kpoints object
            if out_dict['k_points_units'] not in ['2 pi / Angstrom']:
                raise QEOutputParsingError(
                    'Error in kpoints units (should be cartesian)')

            kpoints_from_output = KpointsData()
            kpoints_from_output.set_cell_from_structure(struc)
            kpoints_from_output.set_kpoints(k_points_list,
                                            cartesian=True,
                                            weights=k_points_weights_list)
            kpoints_from_input = self._calc.inp.kpoints

            if not bands_data:
                try:
                    kpoints_from_input.get_kpoints()
                except AttributeError:
                    new_nodes_list += [(self.get_linkname_out_kpoints(),
                                        kpoints_from_output)]

            # Converting bands into a BandsData object (including the kpoints)
            if bands_data:
                kpoints_for_bands = kpoints_from_output

                try:
                    kpoints_from_input.get_kpoints()
                    kpoints_for_bands.labels = kpoints_from_input.labels
                except (AttributeError, ValueError, TypeError):
                    # AttributeError: no list of kpoints in input
                    # ValueError: labels from input do not match the output
                    #      list of kpoints (some kpoints are missing)
                    # TypeError: labels are not set, so kpoints_from_input.labels=None
                    pass

                # Get the bands occupations and correct the occupations of QE:
                # If it computes only one component, it occupies it with half number of electrons
                try:
                    bands_data['occupations'][1]
                    the_occupations = bands_data['occupations']
                except IndexError:
                    the_occupations = 2. * numpy.array(
                        bands_data['occupations'][0])

                try:
                    bands_data['bands'][1]
                    bands_energies = bands_data['bands']
                except IndexError:
                    bands_energies = bands_data['bands'][0]

                the_bands_data = BandsData()
                the_bands_data.set_kpointsdata(kpoints_for_bands)
                the_bands_data.set_bands(bands_energies,
                                         units=bands_data['bands_units'],
                                         occupations=the_occupations)

                new_nodes_list += [('output_band', the_bands_data)]
                out_dict['linknames_band'] = ['output_band']

        # Separate the atomic_occupations dictionary in its own node if it is present
        atomic_occupations = out_dict.get('atomic_occupations', {})
        if atomic_occupations:
            out_dict.pop('atomic_occupations')
            atomic_occupations_node = ParameterData(dict=atomic_occupations)
            new_nodes_list.append(
                ('output_atomic_occupations', atomic_occupations_node))

        output_params = ParameterData(dict=out_dict)
        new_nodes_list.append((self.get_linkname_outparams(), output_params))

        if trajectory_data:
            from aiida.orm.data.array.trajectory import TrajectoryData
            from aiida.orm.data.array import ArrayData
            try:
                positions = numpy.array(
                    trajectory_data.pop('atomic_positions_relax'))
                try:
                    cells = numpy.array(
                        trajectory_data.pop('lattice_vectors_relax'))
                    # if KeyError, the MD was at fixed cell
                except KeyError:
                    cells = numpy.array([in_struc.cell] * len(positions))

                symbols = numpy.array(
                    [str(i.kind_name) for i in in_struc.sites])
                stepids = numpy.arange(
                    len(positions))  # a growing integer per step
                # I will insert time parsing when they fix their issues about time
                # printing (logic is broken if restart is on)

                traj = TrajectoryData()
                traj.set_trajectory(
                    stepids=stepids,
                    cells=cells,
                    symbols=symbols,
                    positions=positions,
                )
                for x in trajectory_data.iteritems():
                    traj.set_array(x[0], numpy.array(x[1]))
                new_nodes_list.append(
                    (self.get_linkname_outtrajectory(), traj))

            except KeyError:
                # forces, atomic charges and atomic mag. moments, in scf calculation (when outputed)
                arraydata = ArrayData()
                for x in trajectory_data.iteritems():
                    arraydata.set_array(x[0], numpy.array(x[1]))
                new_nodes_list.append(
                    (self.get_linkname_outarray(), arraydata))

        return successful, new_nodes_list
Exemplo n.º 18
0
    def parse_with_retrieved(self, retrieved):
        """
        Receives in input a dictionary of retrieved nodes.
        Does all the logic here.
        """
        from aiida.common.exceptions import InvalidOperation
        import os
        import glob

        successful = True

        # check if I'm not to overwrite anything
        #state = self._calc.get_state()
        #if state != calc_states.PARSING:
        #    raise InvalidOperation("Calculation not in {} state"
        #                           .format(calc_states.PARSING) )

        # retrieve the input parameter
        calc_input = self._calc.inp.parameters

        # look for eventual flags of the parser
        try:
            parser_opts = self._calc.inp.settings.get_dict()[
                self.get_parser_settings_key()]
        except (AttributeError, KeyError):
            parser_opts = {}

        # load the input dictionary
        # TODO: pass this input_dict to the parser. It might need it.
        input_dict = self._calc.inp.parameters.get_dict()

        # Check that the retrieved folder is there
        try:
            out_folder = retrieved[self._calc._get_linkname_retrieved()]
        except KeyError:
            self.logger.error("No retrieved folder found")
            return False, ()

        # check what is inside the folder
        list_of_files = out_folder.get_folder_list()
        # at least the stdout should exist
        if not self._calc._OUTPUT_FILE_NAME in list_of_files:
            self.logger.error("Standard output not found")
            successful = False
            return successful, ()
        # if there is something more, I note it down, so to call the raw parser
        # with the right options
        # look for xml
        has_xml = False
        if self._calc._DATAFILE_XML_BASENAME in list_of_files:
            has_xml = True
        # look for bands
        has_bands = False
        if glob.glob(os.path.join(out_folder.get_abs_path('.'), 'K*[0-9]')):
            # Note: assuming format of kpoints subfolder is K*[0-9]
            has_bands = True
            # TODO: maybe it can be more general than bands only?
        out_file = os.path.join(out_folder.get_abs_path('.'),
                                self._calc._OUTPUT_FILE_NAME)
        xml_file = os.path.join(out_folder.get_abs_path('.'),
                                self._calc._DATAFILE_XML_BASENAME)
        dir_with_bands = out_folder.get_abs_path('.')

        # call the raw parsing function
        parsing_args = [out_file, input_dict, parser_opts]
        if has_xml:
            parsing_args.append(xml_file)
        if has_bands:
            if not has_xml:
                self.logger.warning("Cannot parse bands if xml file not "
                                    "found")
            else:
                parsing_args.append(dir_with_bands)

        out_dict, trajectory_data, structure_data, raw_successful = parse_raw_output(
            *parsing_args)

        # if calculation was not considered failed already, use the new value
        successful = raw_successful if successful else successful

        new_nodes_list = []

        # I eventually save the new structure. structure_data is unnecessary after this
        in_struc = self._calc.get_inputs_dict()['structure']
        type_calc = input_dict['CONTROL']['calculation']
        struc = in_struc
        if type_calc in ['relax', 'vc-relax', 'md', 'vc-md']:
            if 'cell' in structure_data.keys():
                struc = convert_qe2aiida_structure(structure_data,
                                                   input_structure=in_struc)
                new_nodes_list.append(
                    (self.get_linkname_outstructure(), struc))

        k_points_list = trajectory_data.pop('k_points', None)
        k_points_weights_list = trajectory_data.pop('k_points_weights', None)

        if k_points_list is not None:

            # build the kpoints object
            if out_dict['k_points_units'] not in ['2 pi / Angstrom']:
                raise QEOutputParsingError(
                    'Error in kpoints units (should be cartesian)')
            # converting bands into a BandsData object (including the kpoints)

            kpoints_from_output = KpointsData()
            kpoints_from_output.set_cell_from_structure(struc)
            kpoints_from_output.set_kpoints(k_points_list,
                                            cartesian=True,
                                            weights=k_points_weights_list)
            kpoints_from_input = self._calc.inp.kpoints
            try:
                kpoints_from_input.get_kpoints()
            except AttributeError:
                new_nodes_list += [(self.get_linkname_out_kpoints(),
                                    kpoints_from_output)]

        # convert the dictionary into an AiiDA object
        output_params = ParameterData(dict=out_dict)
        # return it to the execmanager
        new_nodes_list.append((self.get_linkname_outparams(), output_params))

        if trajectory_data:
            import numpy
            from aiida.orm.data.array.trajectory import TrajectoryData
            from aiida.orm.data.array import ArrayData

            try:
                positions = numpy.array(
                    trajectory_data.pop('atomic_positions_relax'))
                try:
                    cells = numpy.array(
                        trajectory_data.pop('lattice_vectors_relax'))
                    # if KeyError, the MD was at fixed cell
                except KeyError:
                    cells = numpy.array([in_struc.cell] * len(positions))

                symbols = numpy.array(
                    [str(i.kind_name) for i in in_struc.sites])
                stepids = numpy.arange(
                    len(positions))  # a growing integer per step
                # I will insert time parsing when they fix their issues about time
                # printing (logic is broken if restart is on)

                traj = TrajectoryData()
                traj.set_trajectory(
                    stepids=stepids,
                    cells=cells,
                    symbols=symbols,
                    positions=positions,
                )
                for x in trajectory_data.iteritems():
                    traj.set_array(x[0], numpy.array(x[1]))
                # return it to the execmanager
                new_nodes_list.append(
                    (self.get_linkname_outtrajectory(), traj))

            except KeyError:  # forces in scf calculation (when outputed)
                arraydata = ArrayData()
                for x in trajectory_data.iteritems():
                    arraydata.set_array(x[0], numpy.array(x[1]))
                # return it to the execmanager
                new_nodes_list.append(
                    (self.get_linkname_outarray(), arraydata))

        return successful, new_nodes_list
Exemplo n.º 19
0
    def parse_with_retrieved(self, retrieved):
        """
        Parse the output nodes for a PwCalculations from a dictionary of retrieved nodes.
        Two nodes that are expected are the default 'retrieved' FolderData node which will
        store the retrieved files permanently in the repository. The second required node
        is the unstored FolderData node with the temporary retrieved files, which should
        be passed under the key 'retrieved_temporary_folder_key' of the Parser class.

        :param retrieved: a dictionary of retrieved nodes
        """
        import os
        import numpy

        successful = True

        # Load the input dictionary
        parameters = self._calc.inp.parameters.get_dict()

        # Look for optional settings input node and potential 'parser_options' dictionary within it
        try:
            settings = self._calc.inp.settings.get_dict()
            parser_opts = settings[self.get_parser_settings_key()]
        except (AttributeError, KeyError):
            settings = {}
            parser_opts = {}

        # Check that the retrieved folder is there
        try:
            out_folder = retrieved[self._calc._get_linkname_retrieved()]
        except KeyError:
            self.logger.error("No retrieved folder found")
            return False, ()

        # Verify that the retrieved_temporary_folder is within the arguments if temporary files were specified
        if self._calc._get_retrieve_temporary_list():
            try:
                temporary_folder = retrieved[self.retrieved_temporary_folder_key]
                dir_with_bands = temporary_folder.get_abs_path('.')
            except KeyError:
                self.logger.error('the {} was not passed as an argument'.format(self.retrieved_temporary_folder_key))
                return False, ()
        else:
            dir_with_bands = None

        list_of_files = out_folder.get_folder_list()

        # The stdout is required for parsing
        if not self._calc._OUTPUT_FILE_NAME in list_of_files:
            self.logger.error("The standard output file '{}' was not found but is required".format(self._calc._OUTPUT_FILE_NAME))
            return False, ()

        # The xml file is required for parsing
        if not self._calc._DATAFILE_XML_BASENAME in list_of_files:
            self.logger.error("The xml output file '{}' was not found but is required".format(self._calc._DATAFILE_XML_BASENAME))
            successful = False
            xml_file = None
        else:
            xml_file = os.path.join(out_folder.get_abs_path('.'), self._calc._DATAFILE_XML_BASENAME)

        out_file = os.path.join(out_folder.get_abs_path('.'), self._calc._OUTPUT_FILE_NAME)

        # Call the raw parsing function
        parsing_args = [out_file, parameters, parser_opts, xml_file, dir_with_bands]
        out_dict, trajectory_data, structure_data, bands_data, raw_successful = parse_raw_output(*parsing_args)

        # If calculation was not considered failed already, use the new value
        successful = raw_successful if successful else successful

        # The symmetry info has large arrays, that occupy most of the database.
        # turns out most of this is due to 64 matrices that are repeated over and over again.
        # therefore I map part of the results in a list of dictionaries wrote here once and for all
        # if the parser_opts has a key all_symmetries set to True, I don't reduce it
        all_symmetries = parser_opts.get('all_symmetries', False)
        if not all_symmetries:
            try:
                if 'symmetries' in out_dict.keys():
                    old_symmetries = out_dict['symmetries']
                    new_symmetries = []
                    for this_sym in old_symmetries:
                        name = this_sym['name']
                        index = None
                        for i,this in enumerate(self._possible_symmetries):
                            if name in this['name']:
                                index = i
                        if index is None:
                            self.logger.error("Symmetry {} not found".format(name))
                        new_dict = {}
                        # note: here I lose the information about equivalent
                        # ions and fractional_translation.
                        # They will be present with all_symmetries=True
                        new_dict['t_rev'] = this_sym['t_rev']
                        new_dict['symmetry_number'] = index
                        new_symmetries.append(new_dict)
                    out_dict['symmetries'] = new_symmetries # and overwrite the old one
            except KeyError: # no symmetries were parsed (failed case, likely)
                self.logger.error("No symmetries were found in output")

        new_nodes_list = []

        # I eventually save the new structure. structure_data is unnecessary after this
        in_struc = self._calc.get_inputs_dict()['structure']
        type_calc = parameters['CONTROL']['calculation']
        struc = in_struc
        if type_calc in ['relax', 'vc-relax', 'md', 'vc-md']:
            if 'cell' in structure_data.keys():
                struc = convert_qe2aiida_structure(structure_data, input_structure=in_struc)
                new_nodes_list.append((self.get_linkname_outstructure(), struc))

        k_points_list = trajectory_data.pop('k_points', None)
        k_points_weights_list = trajectory_data.pop('k_points_weights', None)

        if k_points_list is not None:

            # Build the kpoints object
            if out_dict['k_points_units'] not in ['2 pi / Angstrom']:
                raise QEOutputParsingError('Error in kpoints units (should be cartesian)')

            kpoints_from_output = KpointsData()
            kpoints_from_output.set_cell_from_structure(struc)
            kpoints_from_output.set_kpoints(k_points_list, cartesian=True, weights=k_points_weights_list)
            kpoints_from_input = self._calc.inp.kpoints

            if not bands_data:
                try:
                    kpoints_from_input.get_kpoints()
                except AttributeError:
                    new_nodes_list += [(self.get_linkname_out_kpoints(), kpoints_from_output)]

            # Converting bands into a BandsData object (including the kpoints)
            if bands_data:
                kpoints_for_bands = kpoints_from_output

                try:
                    kpoints_from_input.get_kpoints()
                    kpoints_for_bands.labels = kpoints_from_input.labels
                except (AttributeError, ValueError, TypeError):
                    # AttributeError: no list of kpoints in input
                    # ValueError: labels from input do not match the output
                    #      list of kpoints (some kpoints are missing)
                    # TypeError: labels are not set, so kpoints_from_input.labels=None
                    pass

                # Get the bands occupations and correct the occupations of QE:
                # If it computes only one component, it occupies it with half number of electrons
                try:
                    bands_data['occupations'][1]
                    the_occupations = bands_data['occupations']
                except IndexError:
                    the_occupations = 2.*numpy.array(bands_data['occupations'][0])

                try:
                    bands_data['bands'][1]
                    bands_energies = bands_data['bands']
                except IndexError:
                    bands_energies = bands_data['bands'][0]

                the_bands_data = BandsData()
                the_bands_data.set_kpointsdata(kpoints_for_bands)
                the_bands_data.set_bands(bands_energies,
                                         units = bands_data['bands_units'],
                                         occupations = the_occupations)

                new_nodes_list += [('output_band', the_bands_data)]
                out_dict['linknames_band'] = ['output_band']

        # Separate the atomic_occupations dictionary in its own node if it is present
        atomic_occupations = out_dict.get('atomic_occupations', {})
        if atomic_occupations:
            out_dict.pop('atomic_occupations')
            atomic_occupations_node = ParameterData(dict=atomic_occupations)
            new_nodes_list.append(('output_atomic_occupations', atomic_occupations_node))

        output_params = ParameterData(dict=out_dict)
        new_nodes_list.append((self.get_linkname_outparams(), output_params))

        if trajectory_data:
            from aiida.orm.data.array.trajectory import TrajectoryData
            from aiida.orm.data.array import ArrayData
            try:
                positions = numpy.array( trajectory_data.pop('atomic_positions_relax'))
                try:
                    cells = numpy.array( trajectory_data.pop('lattice_vectors_relax'))
                    # if KeyError, the MD was at fixed cell
                except KeyError:
                    cells = numpy.array([in_struc.cell] * len(positions))

                symbols = numpy.array([str(i.kind_name) for i in in_struc.sites])
                stepids = numpy.arange(len(positions)) # a growing integer per step
                # I will insert time parsing when they fix their issues about time
                # printing (logic is broken if restart is on)

                traj = TrajectoryData()
                traj.set_trajectory(
                    stepids = stepids,
                    cells = cells,
                    symbols = symbols,
                    positions = positions,
                )
                for x in trajectory_data.iteritems():
                    traj.set_array(x[0],numpy.array(x[1]))
                new_nodes_list.append((self.get_linkname_outtrajectory(),traj))

            except KeyError:
                # forces, atomic charges and atomic mag. moments, in scf calculation (when outputed)
                arraydata = ArrayData()
                for x in trajectory_data.iteritems():
                    arraydata.set_array(x[0],numpy.array(x[1]))
                new_nodes_list.append((self.get_linkname_outarray(),arraydata))

        return successful, new_nodes_list
def submit_stress_tensor(**kwargs):
    # get code
    #code = Code.get(label='pw.sirius.x', computername='piz_daint', useremail='*****@*****.**')
    code = test_and_get_code('pw.sirius.x', expected_code_type='quantumespresso.pw')
    #code.set_prepend_text(prep_text)

    # calculation should always belong to some group, otherwise things get messy after some time
    stress_tensor_grp, created = Group.get_or_create(name=kwargs['group'])
    
    # create parameters
    params = create_calculation_parameters(code,
                                           kwargs.get('partition', 'cpu'),
                                           kwargs.get('num_ranks_per_node', 36),
                                           kwargs.get('num_ranks_kp', 1),
                                           kwargs.get('num_ranks_diag', 1))
    # load structure
    structure = load_node(kwargs['structure_pk'])
    
    # generate k-points
    params['kpoints'] = KpointsData()
    params['kpoints'].set_kpoints_mesh(kwargs.get('kmesh', [24, 24, 24]), offset=(0.0, 0.0, 0.0))
    params['atomic_files'] = kwargs['atomic_files']
    params['calculation_wallclock_seconds'] = kwargs.get('time_limit', 3600)
    params['structure'] = structure
    params['num_points'] = 5
    params['group'] = kwargs['group']
    params['kpoints'].store()
    params['calculation_parameters'].store()
    params['calculation_settings'].store()

    stress_tensor_dict = {}
    stress_tensor_dict['label'] = 'stress_tensor_' + structure.get_formula() + '_' + code.label
    stress_tensor_dict['description'] = "Stress tensor for structure with PK=%i"%structure.pk
    stress_tensor_dict['calc_pk'] = []
    stress_tensor_dict['num_points'] = params['num_points']
    stress_tensor_dict['structure_pk'] = structure.pk
    stress_tensor_dict['code_pk'] = code.pk
    stress_tensor_dict['job_tag'] = params['job_tag']

    # volume scales from 0.94 to 1.06, alat scales as pow(1/3)
    scales = np.linspace(0.992, 1.008, num=params['num_points']).tolist()

    eps = np.linspace(-0.008, 0.008, num=params['num_points']).tolist()
    #scales = np.linspace(0.99, 1.05, num=params['num_points']).tolist()

    use_symmetry = .False.

    if use_symmetry:
       SGN = get_space_group_number(structure_id=structure_id)
    else:
       SGN = 1

    LC = self.get_Laue_dict(space_group_number=SGN)

    def_list = get_Lagrange_distorted_index(structure_id=structure_id, LC=LC)

    SCs = len(def_list)

    alat_steps = params['num_points']

    distorted_structure_index = []
    eps_index = 0
    for i in def_list:
        for a in eps:

            eps_index = eps_index + 1

            distorted_structure_index.append(eps_index)

    for ii in distorted_structure_index:

        a = eps[ii % alat_steps - 1]
        i = def_list[int((ii - 1) / alat_steps)]

        M_Lagrange_eps = get_Lagrange_strain_matrix(eps=a, def_mtx_index=i)

        structure_new = get_Lagrange_distorted_structure(structure_id=structure_id, M_Lagrange_eps=M_Lagrange_eps)

        structure_new.store()
        
        calc_label = 'gs_' + structure.get_formula() + '_' + code.label
        calc_desc = params['job_tag']
    
        # create calculation
        calc = create_calculation(structure_new, params, calc_label, calc_desc)
        calc.store()
        print "created calculation with uuid='{}' and PK={}".format(calc.uuid, calc.pk)
        stress_tensor_grp.add_nodes([calc])
        calc.submit()
        stress_tensor_dict['calc_pk'].append(calc.pk)
    
    stress_tensor_node = ParameterData(dict=stress_tensor_dict)
    stress_tensor_node.store()
    stress_tensor_grp.add_nodes([stress_tensor_node])
    print "created stress tensor node with uuid='{}' and PK={}".format(stress_tensor_node.uuid, stress_tensor_node.pk)
Exemplo n.º 21
0
from aiida.orm.data.base import Str, Int
from aiida.orm.data.array.kpoints import KpointsData
from aiida.orm.data.parameter import ParameterData
from aiida.workflows.user.base import VASPBaseWorkChain

VaspCalculation = CalculationFactory('vasp.vasp')

options = {
	'resources': {
		'num_machines': 1,
		'tot_num_mpiprocs': 1,
	},
	'max_wallclock_seconds': 1800,
}

kpoints = KpointsData()
kpoints.set_kpoints_mesh([1, 1, 1])

inputs = {
	'code': Code.get_from_string('VASP.5.4.4@Raichu'),
	'structure': load_node(888),
	'kpoints': kpoints,
	'parameters': ParameterData(dict={}),
	'settings': ParameterData(dict={}),
	'pseudo_family': Str('vasp-pbe'),
        'options' : ParameterData( dict = { 
                      'max_wallclock_seconds' : 3600,
                      'max_memory_kb': 10000000,
                      'resources' : { 'num_machines': 1
                                    },
                    }),
Exemplo n.º 22
0
            'tot_num_mpiprocs': 28,
        },
        'max_wallclock_seconds': 60 * 60 * 10,
    })
wannier90_parameters = ParameterData(
    dict={
        'bands_plot': False,
        'num_iter': 12,
        'guiding_centres': True,
        'num_wann': 4,
        #'exclude_bands': exclude_bands,
        # 'wannier_plot':True,
        # 'wannier_plot_list':[1]
    })
structure = load_node(152)
scf_kpoints = KpointsData()
scf_kpoints.set_kpoints_mesh([4, 4, 4])
nscf_kpoints = KpointsData()
nscf_kpoints.set_kpoints_mesh([4, 4, 4])
projections = List()
projections.extend(['As:s', 'As:p'])
wc = submit(
    SimpleWannier90WorkChain,
    pw_code=Code.get_from_string('pw_6.1@fidis'),
    pw2wannier90_code=Code.get_from_string('pw2wannier90_6.1@fidis'),
    wannier90_code=Code.get_from_string('wannier90_2.1@fidis'),
    #orbital_projections=projections,
    structure=structure,
    pseudo_family=Str('SSSP_efficiency_v0.95'),
    #wannier90_parameters=wannier90_parameters,
    scf={
Exemplo n.º 23
0
def execute(args):
    """
    The main execution of the script, which will run some preliminary checks on the command
    line arguments before passing them to the workchain and running it
    """
    try:
        siesta_code = Code.get_from_string(args.siesta_codename)
    except NotExistent as exception:
        print "Execution failed: could not retrieve the code '{}'".format(
            args.siesta_codename)
        print "Exception report: {}".format(exception)
        return

    try:
        gollum_code = Code.get_from_string(args.gollum_codename)
    except NotExistent as exception:
        print "Execution failed: could not retrieve the code '{}'".format(
            args.gollum_codename)
        print "Exception report: {}".format(exception)
        return

    protocol = Str(args.protocol)

    ###### Siesta structures ##############################
    alat = 1.00  # Angstrom. Not passed to the fdf file

    # Leads
    cellle = [[
        20.,
        0.,
        0.,
    ], [
        0.,
        20.,
        0.,
    ], [
        0.,
        0.,
        5.,
    ]]
    sle = StructureData(cell=cellle)
    for i in range(0, 2):
        sle.append_atom(position=(0., 0., i * 2.5), symbols=['Au'])

    if args.structure_em > 0:
        structure_le = load_node(args.structure_le)
    else:
        structure_le = sle

    # Extended molecule
    cellem = [[
        20.,
        0.,
        0.,
    ], [
        0.,
        20.,
        0.,
    ], [
        0.,
        0.,
        45.,
    ]]
    sem = StructureData(cell=cellem)
    for i in range(0, 18):
        sem.append_atom(position=(0., 0., i * 2.5), symbols=['Au'])

    if args.structure_em > 0:
        structure_em = load_node(args.structure_em)
    else:
        structure_em = sem

    ###### Siesta k-ppoints ###############################
    kpoints_le = KpointsData()
    kpoints_le.set_kpoints_mesh([1, 1, 90])

    kpoints_em = KpointsData()
    kpoints_em.set_kpoints_mesh([1, 1, 10])

    ###### Gollum parameters ##############################
    # The "atom" block is definied independently
    pms = {
        'NBlock leadp': """
        2 2 -1
        2 2 1 """,
        'atom': """
        1 2  2
        0 0 10
        2 2  2 """
    }
    parameters = ParameterData(dict=pms)

    ######

    run(GollumSiestaWorkChain,
        siesta_code=siesta_code,
        gollum_code=gollum_code,
        structure_le=structure_le,
        structure_em=structure_em,
        protocol=protocol,
        kpoints_le=kpoints_le,
        kpoints_em=kpoints_em,
        parameters=parameters)
Exemplo n.º 24
0
    def get_kpointsdata(self):
        """
        Return a KpointsData object based on the data in the input file.

        This uses all of the data in the input file to do the necessary unit
        conversion, ect. and then creates an AiiDa KpointsData object.


        **Note:** If the calculation uses only the gamma k-point (`if
        self.k_points['type'] == 'gamma'`), it is necessary to also attach a
        settings node to the calculation with `gamma_only = True`.

        :return: KpointsData object of the kpoints in the input file
        :rtype: aiida.orm.data.array.kpoints.KpointsData
        :raises NotImplementedError: if the kpoints are
            in a format not yet supported.
        """
        from aiida.orm.data.array.kpoints import KpointsData
        # Initialize the KpointsData node
        kpointsdata = KpointsData()
        # Get the structure using this class's method.
        structuredata = self.get_structuredata()
        # Set the structure information of the kpoints node.
        kpointsdata.set_cell_from_structure(structuredata)

        # Set the kpoints and weights, doing any necessary units conversion.
        if self.k_points['type'] == 'crystal':  # relative to recip latt vecs
            kpointsdata.set_kpoints(self.k_points['points'],
                                    weights=self.k_points['weights'])
        elif self.k_points['type'] == 'tpiba':  # cartesian; units of 2*pi/alat
            alat = np.linalg.norm(structuredata.cell[0])  # alat in Angstrom
            kpointsdata.set_kpoints(np.array(self.k_points['points']) *
                                    (2. * np.pi / alat),
                                    weights=self.k_points['weights'],
                                    cartesian=True)
        elif self.k_points['type'] == 'automatic':
            kpointsdata.set_kpoints_mesh(self.k_points['points'],
                                         offset=self.k_points['offset'])
        elif self.k_points['type'] == 'gamma':
            kpointsdata.set_kpoints_mesh([1, 1, 1])
        else:
            raise NotImplementedError(
                'Support for creating KpointsData from input units of {} is'
                'not yet implemented'.format(self.k_points['type']))

        return kpointsdata
Exemplo n.º 25
0
def band_parser(band_dat_path, band_kpt_path, special_points, structure):
    """
    Parsers the bands output data, along with the special points retrieved
    from the input kpoints to construct a BandsData object which is then
    returned. Cannot handle discontinuities in the kpath, if two points are
    assigned to same spot only one will be passed.

    :param band_dat_path: file path to the aiida_band.dat file
    :param band_kpt_path: file path to the aiida_band.kpt file
    :param special_points: special points to add labels to the bands a dictionary in
        the form expected in the input as described in the wannier90 documentation
    :return: BandsData object constructed from the input params
    """
    import numpy as np
    from aiida.orm.data.array.bands import BandsData
    from aiida.orm.data.array.kpoints import KpointsData

    # imports the data
    out_kpt = np.genfromtxt(band_kpt_path, skip_header=1, usecols=(0, 1, 2))
    out_dat = np.genfromtxt(band_dat_path, usecols=1)

    # reshaps the output bands
    out_dat = out_dat.reshape(len(out_kpt), (len(out_dat) / len(out_kpt)),
                              order="F")

    # finds expected points of discontinuity
    kpath = special_points['path']
    cont_break = [(i, (kpath[i - 1][1], kpath[i][0]))
                  for i in range(1, len(kpath))
                  if kpath[i - 1][1] != kpath[i][0]]

    # finds the special points
    special_points_dict = special_points['point_coords']
    labels = [(i, k) for k in special_points_dict for i in range(len(out_kpt))
              if all(np.isclose(special_points_dict[k], out_kpt[i]))]
    labels.sort()

    # Checks and appends labels if discontinuity
    appends = []
    for x in cont_break:
        # two cases the break is before or the break is after
        # if the break is before
        if labels[x[0]][1] != x[1][0]:
            # checks to see if the discontinuity was already there
            if labels[x[0] - 1] == x[1][0]:
                continue
            else:
                insert_point = x[0]
                new_label = x[1][0]
                kpoint = labels[x[0]][0] - 1
                appends += [[insert_point, new_label, kpoint]]
        # if the break is after
        if labels[x[0]][1] != x[1][1]:
            # checks to see if the discontinuity was already there
            if labels[x[0] + 1] == x[1][1]:
                continue
            else:
                insert_point = x[0] + 1
                new_label = x[1][1]
                kpoint = labels[x[0]][0] + 1
                appends += [[insert_point, new_label, kpoint]]
    appends.sort()
    for i in range(len(appends)):
        append = appends[i]
        labels.insert(append[0] + i, (append[2], unicode(append[1])))
    bands = BandsData()
    k = KpointsData()
    k.set_cell_from_structure(structure)
    k.set_kpoints(out_kpt, cartesian=False)
    bands.set_kpointsdata(k)
    bands.set_bands(out_dat, units='eV')
    bands.labels = labels
    return bands
def execute(args):
    """
    The main execution of the script, which will run some preliminary checks on the command
    line arguments before passing them to the workchain and running it
    """
    try:
        code = Code.get_from_string(args.codename)
    except NotExistent as exception:
        print "Execution failed: could not retrieve the code '{}'".format(args.codename)
        print "Exception report: {}".format(exception)
        return

    try:
        structure = load_node(args.structure)
    except NotExistent as exception:
        print "Execution failed: failed to load the node for the given structure pk '{}'".format(args.structure)
        print "Exception report: {}".format(exception)
        return

    if not isinstance(structure, StructureData):
        print "The provided pk {} for the structure does not correspond to StructureData, aborting...".format(args.parent_calc)
        return

    kpoints = KpointsData()
    kpoints.set_kpoints_mesh(args.kpoints)

    parameters = {
        'xc:functional': 'LDA',
        'xc:authors': 'CA',
        'spinpolarized': True,
        'meshcutoff': '40.000 Ry',
        'dm:numberpulay': 4,
        'dm:mixingweight': 0.3,
        'dm:tolerance': 1.e-3,
        'max-scfiterations': 3,
        'scf-must-converge': True,
        'Solution-method': 'diagon',
        'electronic-temperature': '25 meV',
        'md-typeofrun': 'CG',
        'md-numcgsteps': 0,
        'md-maxcgdispl': '0.1 Ang',
        'md-maxforcetol': '0.04 eV/Ang',
        'writeforces': True,
        'writecoorstep': True
    }
    basis = {
        'pao-energy-shift': '300 meV',
        '%block pao-basis-sizes': """
        Si DZP                    """,
    }
    settings = {}
    options  = {
        'resources': {
            'num_machines': 1
        },
        'max_wallclock_seconds': args.max_wallclock_seconds,
    }

    run(
        SiestaBaseWorkChain,
        code=code,
        structure=structure,
        pseudo_family=Str(args.pseudo_family),
        kpoints=kpoints,
        parameters=ParameterData(dict=parameters),
        settings=ParameterData(dict=settings),
        options=ParameterData(dict=options),
        basis=ParameterData(dict=basis),
        max_iterations=Int(args.max_iterations),
    )
Exemplo n.º 27
0
def execute(args):
    """
    The main execution of the script, which will run some preliminary checks on the command
    line arguments before passing them to the workchain and running it
    """
    try:
        code = Code.get_from_string(args.codename)
    except NotExistent as exception:
        print "Execution failed: could not retrieve the code '{}'".format(
            args.codename)
        print "Exception report: {}".format(exception)
        return

    try:
        structure = load_node(args.structure)
    except NotExistent as exception:
        print "Execution failed: failed to load the node for the given structure pk '{}'".format(
            args.structure)
        print "Exception report: {}".format(exception)
        return

    if not isinstance(structure, StructureData):
        print "The provided pk {} for the structure does not correspond to StructureData, aborting...".format(
            args.parent_calc)
        return

    kpoints = KpointsData()
    kpoints.set_kpoints_mesh(args.kpoints)

    parameters = {
        'xc-functional': 'LDA',
        'xc-authors': 'CA',
        'mesh-cutoff': '100.000 Ry',
        'max-scfiterations': 30,
        'dm-numberpulay': 4,
        'dm-mixingweight': 0.1,
        'dm-tolerance': 1.e-4,
        'md-typeofrun': 'cg',
        'md-numcgsteps': 8,
        'md-maxcgdispl': '0.200 bohr',
        'md-maxforcetol': '0.020 eV/Ang',
        'geometry-must-converge': True,
        'xml-write': True
    }

    # default basis
    basis = {}

    settings = {}
    options = {
        'resources': {
            'num_machines': 1
        },
        'max_wallclock_seconds': args.max_wallclock_seconds,
    }

    run(
        SiestaBaseWorkChain,
        code=code,
        structure=structure,
        pseudo_family=Str(args.pseudo_family),
        kpoints=kpoints,
        parameters=ParameterData(dict=parameters),
        settings=ParameterData(dict=settings),
        options=ParameterData(dict=options),
        basis=ParameterData(dict=basis),
        max_iterations=Int(args.max_iterations),
    )
Exemplo n.º 28
0
    def test_pw_translation(self):
        from aiida.tools.dbexporters.tcod \
            import translate_calculation_specific_values
        # from aiida.tools.dbexporters.tcod_plugins.pw \
        #     import PwTcodtranslator as PWT
        # from aiida.tools.dbexporters.tcod_plugins.cp \
        #     import CpTcodtranslator as CPT
        from aiida.orm.code import Code
        from aiida.orm.data.array import ArrayData
        from aiida.orm.data.array.kpoints import KpointsData
        from aiida.orm.data.parameter import ParameterData
        import numpy
        from aiida.common.pluginloader import get_plugin
        PWT = get_plugin('tools.dbexporters.tcod_plugins',
                         'quantumespresso.pw')
        CPT = get_plugin('tools.dbexporters.tcod_plugins',
                         'quantumespresso.cp')

        code = Code()
        code._set_attr('remote_exec_path', '/test')

        kpoints = KpointsData()
        kpoints.set_kpoints_mesh([2, 3, 4], offset=[0.25, 0.5, 0.75])

        def empty_list():
            return []

        calc = FakeObject({
            "inp": {
                "parameters": ParameterData(dict={}),
                "kpoints": kpoints,
                "code": code
            },
            "out": {
                "output_parameters": ParameterData(dict={})
            },
            "get_inputs": empty_list
        })

        res = translate_calculation_specific_values(calc, PWT)
        self.assertEquals(
            res, {
                '_dft_BZ_integration_grid_X': 2,
                '_dft_BZ_integration_grid_Y': 3,
                '_dft_BZ_integration_grid_Z': 4,
                '_dft_BZ_integration_grid_shift_X': 0.25,
                '_dft_BZ_integration_grid_shift_Y': 0.5,
                '_dft_BZ_integration_grid_shift_Z': 0.75,
                '_dft_pseudopotential_atom_type': [],
                '_dft_pseudopotential_type': [],
                '_dft_pseudopotential_type_other_name': [],
                '_tcod_software_package': 'Quantum ESPRESSO',
                '_tcod_software_executable_path': '/test',
            })

        calc = FakeObject({
            "inp": {
                "parameters":
                ParameterData(dict={
                    'SYSTEM': {
                        'ecutwfc': 40,
                        'occupations': 'smearing'
                    }
                })
            },
            "out": {
                "output_parameters":
                ParameterData(dict={
                    'number_of_electrons': 10,
                })
            },
            "get_inputs": empty_list
        })
        res = translate_calculation_specific_values(calc, PWT)
        self.assertEquals(
            res, {
                '_dft_cell_valence_electrons': 10,
                '_tcod_software_package': 'Quantum ESPRESSO',
                '_dft_BZ_integration_smearing_method': 'Gaussian',
                '_dft_pseudopotential_atom_type': [],
                '_dft_pseudopotential_type': [],
                '_dft_pseudopotential_type_other_name': [],
                '_dft_kinetic_energy_cutoff_EEX': 2176.910676048,
                '_dft_kinetic_energy_cutoff_charge_density': 2176.910676048,
                '_dft_kinetic_energy_cutoff_wavefunctions': 544.227669012,
            })

        calc = FakeObject({
            "inp": {
                "parameters": ParameterData(dict={})
            },
            "out": {
                "output_parameters": ParameterData(dict={
                    'energy_xc': 5,
                })
            },
            "get_inputs": empty_list
        })
        with self.assertRaises(ValueError):
            translate_calculation_specific_values(calc, PWT)

        calc = FakeObject({
            "inp": {
                "parameters": ParameterData(dict={})
            },
            "out": {
                "output_parameters":
                ParameterData(dict={
                    'energy_xc': 5,
                    'energy_xc_units': 'meV'
                })
            },
            "get_inputs": empty_list
        })
        with self.assertRaises(ValueError):
            translate_calculation_specific_values(calc, PWT)

        energies = {
            'energy': -3701.7004199449257,
            'energy_one_electron': -984.0078459766,
            'energy_xc': -706.6986753641559,
            'energy_ewald': -2822.6335103043157,
            'energy_hartree': 811.6396117001462,
            'fermi_energy': 10.25208617898623,
        }
        dct = energies
        for key in energies.keys():
            dct["{}_units".format(key)] = 'eV'
        calc = FakeObject({
            "inp": {
                "parameters":
                ParameterData(dict={'SYSTEM': {
                    'smearing': 'mp'
                }})
            },
            "out": {
                "output_parameters": ParameterData(dict=dct)
            },
            "get_inputs": empty_list
        })
        res = translate_calculation_specific_values(calc, PWT)
        self.assertEquals(
            res, {
                '_tcod_total_energy': energies['energy'],
                '_dft_1e_energy': energies['energy_one_electron'],
                '_dft_correlation_energy': energies['energy_xc'],
                '_dft_ewald_energy': energies['energy_ewald'],
                '_dft_hartree_energy': energies['energy_hartree'],
                '_dft_fermi_energy': energies['fermi_energy'],
                '_tcod_software_package': 'Quantum ESPRESSO',
                '_dft_BZ_integration_smearing_method': 'Methfessel-Paxton',
                '_dft_BZ_integration_MP_order': 1,
                '_dft_pseudopotential_atom_type': [],
                '_dft_pseudopotential_type': [],
                '_dft_pseudopotential_type_other_name': [],
            })
        dct = energies
        dct['number_of_electrons'] = 10
        for key in energies.keys():
            dct["{}_units".format(key)] = 'eV'
        calc = FakeObject({
            "inp": {
                "parameters":
                ParameterData(dict={'SYSTEM': {
                    'smearing': 'unknown-method'
                }})
            },
            "out": {
                "output_parameters": ParameterData(dict=dct)
            },
            "get_inputs": empty_list
        })
        res = translate_calculation_specific_values(calc, CPT)
        self.assertEquals(
            res, {
                '_dft_cell_valence_electrons': 10,
                '_tcod_software_package': 'Quantum ESPRESSO'
            })

        ad = ArrayData()
        ad.set_array("forces", numpy.array([[[1, 2, 3], [4, 5, 6]]]))
        calc = FakeObject({
            "inp": {
                "parameters":
                ParameterData(dict={'SYSTEM': {
                    'smearing': 'unknown-method'
                }})
            },
            "out": {
                "output_parameters": ParameterData(dict={}),
                "output_array": ad
            },
            "get_inputs": empty_list
        })
        res = translate_calculation_specific_values(calc, PWT)
        self.assertEquals(
            res,
            {
                '_tcod_software_package': 'Quantum ESPRESSO',
                '_dft_BZ_integration_smearing_method': 'other',
                '_dft_BZ_integration_smearing_method_other': 'unknown-method',
                '_dft_pseudopotential_atom_type': [],
                '_dft_pseudopotential_type': [],
                '_dft_pseudopotential_type_other_name': [],
                ## Residual forces are no longer produced, as they should
                ## be in the same CIF loop with coordinates -- to be
                ## implemented later, since it's not yet clear how.
                # '_tcod_atom_site_resid_force_Cartn_x': [1,4],
                # '_tcod_atom_site_resid_force_Cartn_y': [2,5],
                # '_tcod_atom_site_resid_force_Cartn_z': [3,6],
            })
Exemplo n.º 29
0
    def parse_with_retrieved(self, retrieved):
        """
        Parses the datafolder, stores results.
        This parser for this simple code does simply store in the DB a node
        representing the file of phonon frequencies
        """
        from aiida.common.exceptions import InvalidOperation

        # suppose at the start that the job is successful
        successful = True
        new_nodes_list = []

        # Check that the retrieved folder is there
        try:
            out_folder = retrieved[self._calc._get_linkname_retrieved()]
        except KeyError:
            self.logger.error("No retrieved folder found")
            return False, ()

        # check what is inside the folder
        list_of_files = out_folder.get_folder_list()
        # at least the stdout should exist
        if not self._calc._OUTPUT_FILE_NAME in list_of_files:
            successful = False
            self.logger.error("Standard output not found")
            return successful, ()

        # check that the file has finished (i.e. JOB DONE is inside the file)
        filpath = out_folder.get_abs_path(self._calc._OUTPUT_FILE_NAME)
        with open(filpath, 'r') as fil:
            lines = fil.read()
        if "JOB DONE" not in lines:
            successful = False
            self.logger.error("Computation did not finish properly")

        # check that the phonon frequencies file is present
        try:
            # define phonon frequencies file name
            phonon_file = out_folder.get_abs_path(
                self._calc._PHONON_FREQUENCIES_NAME)
        except OSError:
            successful = False
            self.logger.error("File with phonon frequencies not found")
            return successful, new_nodes_list

        # extract the kpoints from the input data and create the kpointsdata for bands
        kpointsdata = self._calc.inp.kpoints
        try:
            kpoints = kpointsdata.get_kpoints()
            kpointsdata_for_bands = kpointsdata.copy()
        except AttributeError:
            kpoints = kpointsdata.get_kpoints_mesh(print_list=True)
            kpointsdata_for_bands = KpointsData()
            kpointsdata_for_bands.set_kpoints(kpoints)
        # find the number of kpoints
        num_kpoints = kpoints.shape[0]

        # call the raw parsing function
        parsed_data = parse_raw_matdyn_phonon_file(phonon_file)

        # extract number of kpoints read from the file (and take out from output
        # dictionary)
        try:
            this_num_kpoints = parsed_data.pop('num_kpoints')
        except KeyError:
            successful = False
            self.logger.error("Wrong number of kpoints")
            # warning message already in parsed_data
            return successful, new_nodes_list

        # check that the number of kpoints from the file is the same as the one
        # in the input kpoints
        if num_kpoints != this_num_kpoints:
            successful = False
            self.logger.error("Number of kpoints different in input and in "
                              "phonon frequencies file")

        # extract phonon bands (and take out from output dictionary)
        phonon_bands = parsed_data.pop('phonon_bands')

        # save phonon branches into BandsData
        output_bands = BandsData()
        output_bands.set_kpointsdata(kpointsdata_for_bands)
        output_bands.set_bands(phonon_bands, units='THz')

        # convert the dictionary into an AiiDA object (here only warnings remain)
        output_params = ParameterData(dict=parsed_data)

        for message in parsed_data['warnings']:
            self.logger.error(message)

        # prepare the list of output nodes to be returned
        new_nodes_list = [(self.get_linkname_outparams(), output_params),
                          (self.get_linkname_outbands(), output_bands)]

        return successful, new_nodes_list
Exemplo n.º 30
0
def execute(args):
    """
    The main execution of the script, which will run some preliminary checks on the command
    line arguments before passing them to the workchain and running it
    """
    try:
        code = Code.get_from_string(args.codename)
    except NotExistent as exception:
        print "Execution failed: could not retrieve the code '{}'".format(args.codename)
        print "Exception report: {}".format(exception)
        return

    alat = 10.0 # angstrom
    cell = [[alat, 0., 0.,],
            [0., alat, 0.,],
            [0., 0., alat,],
    ]

    # Water molecule
    # One of the H atoms is sligthy moved

    s = StructureData(cell=cell)
    s.append_atom(position=(0.000,0.000,0.00),symbols=['O'])
    s.append_atom(position=(0.757,0.586,0.00),symbols=['H'])
    s.append_atom(position=(-0.780,0.600,0.00),symbols=['H'])


    structure = s


    kpoints = KpointsData()
    kpoints.set_kpoints_mesh(args.kpoints)

    parameters = {
        'meshcutoff': '80.000 Ry',
        'dm:numberpulay': 4,
        'dm:mixingweight': 0.2,
        'dm:tolerance': 1.e-3,
        'max-scfiterations': 30,
        'scf-must-converge': True,
        'geometry-must-converge': True,
        'electronic-temperature': '25 meV',
        'md-typeofrun': 'CG',
        'md-numcgsteps': 6,
        'md-maxcgdispl': '0.1 Ang',
        'md-maxforcetol': '0.03 eV/Ang',
        'xml:write': True
    }
    basis = {
        'pao-energy-shift': '300 meV',
        'pao-basis-size': 'DZP'
    }
    settings = {}
    options  = {
        'resources': {
            'num_machines': 1
        },
        'max_wallclock_seconds': args.max_wallclock_seconds,
    }

    run(
        SiestaBaseWorkChain,
        code=code,
        structure=structure,
        pseudo_family=Str(args.pseudo_family),
        kpoints=kpoints,
        parameters=ParameterData(dict=parameters),
        settings=ParameterData(dict=settings),
        options=ParameterData(dict=options),
        basis=ParameterData(dict=basis),
        max_iterations=Int(args.max_iterations),
    )
Exemplo n.º 31
0
    def run_bands(self):
        """
        Run the SiestaBaseWorkChain in scf+bands mode on the primitive cell of the relaxed input structure
        """
        self.report('Running bands calculation')

        try:
            structure = self.ctx.workchain_relax.out.output_structure
        except:
            self.abort_nowait('failed to get the output structure from the relaxation run')
            return
        
        self.ctx.structure_relaxed_primitive = structure


        inputs = dict(self.ctx.inputs)

        kpoints_mesh = KpointsData()
        kpoints_mesh.set_cell_from_structure(self.ctx.structure_relaxed_primitive)
        kpoints_mesh.set_kpoints_mesh_from_density(
            distance=self.ctx.protocol['kpoints_mesh_density'],
            offset=self.ctx.protocol['kpoints_mesh_offset'])

        bandskpoints = KpointsData()
        bandskpoints.set_cell(structure.cell, structure.pbc)
        bandskpoints.set_kpoints_path(kpoint_distance = 0.05)
        self.ctx.kpoints_path = bandskpoints

        # Final input preparation, wrapping dictionaries in ParameterData nodes
        inputs['bandskpoints'] = self.ctx.kpoints_path           
        inputs['kpoints'] = kpoints_mesh
        inputs['structure'] = self.ctx.structure_relaxed_primitive
        inputs['parameters'] = ParameterData(dict=inputs['parameters'])
        inputs['basis'] = ParameterData(dict=inputs['basis'])
        inputs['settings'] = ParameterData(dict=inputs['settings'])
        
        running = submit(SiestaBaseWorkChain, **inputs)
        
        self.report('launching SiestaBaseWorkChain<{}> in scf+bands mode'.format(running.pid))
        
        return ToContext(workchain_bands=running)