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