Ejemplo n.º 1
0
def create_kpoints_from_distance(structure, distance, force_parity):
    """Generate a uniformly spaced kpoint mesh for a given structure.

    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 numpy import linalg
    from aiida.orm import KpointsData

    epsilon = 1E-5

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

    lengths_vector = [linalg.norm(vector) for vector in structure.cell]
    lengths_kpoint = kpoints.get_kpoints_mesh()[0]

    is_symmetric_cell = all(abs(length - lengths_vector[0]) < epsilon for length in lengths_vector)
    is_symmetric_mesh = all(length == lengths_kpoint[0] for length in lengths_kpoint)

    # If the vectors of the cell all have the same length, the kpoint mesh should be isotropic as well
    if is_symmetric_cell and not is_symmetric_mesh:
        nkpoints = max(lengths_kpoint)
        kpoints.set_kpoints_mesh([nkpoints, nkpoints, nkpoints])

    return kpoints
Ejemplo n.º 2
0
def get_distance_from_kmesh(calc):
    mesh = calc.inputs.kpoints.get_kpoints_mesh()[0]
    k = KpointsData()
    k.set_cell_from_structure(
        calc.inputs.structure
    )  #these take trace of PBC...if set in the inputs.!!
    for i in range(4, 400):
        k.set_kpoints_mesh_from_density(1 / (i * 0.25))
        if k.get_kpoints_mesh()[0] == mesh:
            print('ok, {} is the density'.format(i * 0.25))
            print(k.get_kpoints_mesh()[0], mesh)
            return i * 0.25
Ejemplo n.º 3
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
Ejemplo n.º 4
0
    def _get_kpoints(self, key, structure):
        from aiida.orm import KpointsData
        if "kpoints" in self._protocols[key]:
            kpoints_mesh = KpointsData()
            kpoints_mesh.set_cell_from_structure(structure)
            kp_dict = self._protocols[key]["kpoints"]
            if "offset" in kp_dict:
                kpoints_mesh.set_kpoints_mesh_from_density(
                    distance=kp_dict["distance"], offset=kp_dict["offset"])
            else:
                kpoints_mesh.set_kpoints_mesh_from_density(
                    distance=kp_dict["distance"])
        else:
            kpoints_mesh = None

        return kpoints_mesh
Ejemplo n.º 5
0
    def run_scf_and_ldos(self):
        """
        Run the SiestaBaseWorkChain in scf+ldos mode on the primitive cell of the relaxed input structure
        """

        try:
            structure = self.ctx.workchain_relax.outputs.output_structure
        except:
            return self.exit_codes.ERROR_RELAXED_STRUCTURE_NOT_AVAILABLE

        # Do we need further refinement by Seekpath on this=? (eventually)?
        self.ctx.structure_relaxed_primitive = structure

        inputs = dict(self.ctx.inputs)
        ldos_e = "\n {e1} {e2} eV \n %endblock local-density-of-states".format(
            e1=self.inputs.e1.value, e2=self.inputs.e2.value)
        inputs['parameters']['%block local-density-of-states'] = ldos_e

        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'])

        # Final input preparation, wrapping dictionaries in ParameterData nodes
        inputs['kpoints'] = kpoints_mesh
        inputs['structure'] = self.ctx.structure_relaxed_primitive
        inputs['parameters'] = Dict(dict=inputs['parameters'])
        inputs['basis'] = Dict(dict=inputs['basis'])
        inputs['settings'] = Dict(dict=inputs['settings'])
        inputs['options'] = Dict(dict=inputs['options'])

        running = self.submit(SiestaBaseWorkChain, **inputs)
        self.report('launched SiestaBaseWorkChain<{}> in scf+ldos mode'.format(
            running.pk))

        return ToContext(workchain_base_ldos=running)
Ejemplo n.º 6
0
    def _get_kpoints(self, key, structure, previous_workchain):
        from aiida.orm import KpointsData
        if previous_workchain:
            kpoints_mesh = KpointsData()
            kpoints_mesh.set_cell_from_structure(structure)
            previous_wc_kp = previous_workchain.inputs.kpoints
            kpoints_mesh.set_kpoints_mesh(
                previous_wc_kp.get_attribute('mesh'),
                previous_wc_kp.get_attribute('offset'))
            return kpoints_mesh

        if 'kpoints' in self._protocols[key]:
            kpoints_mesh = KpointsData()
            kpoints_mesh.set_cell_from_structure(structure)
            kp_dict = self._protocols[key]['kpoints']
            if 'offset' in kp_dict:
                kpoints_mesh.set_kpoints_mesh_from_density(
                    distance=kp_dict['distance'], offset=kp_dict['offset'])
            else:
                kpoints_mesh.set_kpoints_mesh_from_density(
                    distance=kp_dict['distance'])
            return kpoints_mesh

        return None
Ejemplo n.º 7
0
    def run_bands(self):
        """
        Run the SiestaBaseWorkChain in scf+bands mode on the primitive cell of the relaxed input structure
        """

        try:
            structure = self.ctx.workchain_relax.outputs.output_structure
        except:
            return self.exit_codes.ERROR_RELAXED_STRUCTURE_NOT_AVAILABLE

        # Do we need further refinement by Seekpath on this=? (eventually)?
        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'])

        # For the band-structure kath, it is advised to use the
        # 'seekpath' method, but we try the 'legacy' for now.  In some
        # cases we might not want seekpath to change our structure.
        # Further support for this in the input to the workflow might
        # be needed.  (NOTE: If we ever optimize this workflow to
        # re-use the DM or H resulting from the execution of the Base
        # workflow, a change in structure would cause errors.)

        from aiida.tools import get_explicit_kpoints_path

        legacy_kpath_parameters = Dict(
            dict={
                'kpoint_distance':
                0.05  # In units of b1, b2, b3 (Around 20 points per side...)
            })
        seekpath_kpath_parameters = Dict(dict={
            'reference_distance': 0.02,
            'symprec': 0.0001
        })
        kpath_parameters = legacy_kpath_parameters

        result = get_explicit_kpoints_path(
            self.ctx.structure_relaxed_primitive,
            method='legacy',
            **kpath_parameters.get_dict())
        bandskpoints = result['explicit_kpoints']
        # The 'legacy' method presumably does not change the structure
        ## structure = result['primitive_structure']

        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'] = Dict(dict=inputs['parameters'])
        inputs['basis'] = Dict(dict=inputs['basis'])
        inputs['settings'] = Dict(dict=inputs['settings'])

        running = self.submit(SiestaBaseWorkChain, **inputs)
        self.report(
            'launched SiestaBaseWorkChain<{}> in scf+bands mode'.format(
                running.pk))

        return ToContext(workchain_base_bands=running)