def test_get_kpoints(self): """Test the `get_kpoints` method.""" kpt = KpointsData() kpt.set_cell_from_structure(self.structure) kpoints = [ [0., 0., 0.], [0.5, 0.5, 0.5], ] cartesian_kpoints = [ [0., 0., 0.], [np.pi / self.alat, np.pi / self.alat, np.pi / self.alat], ] kpt.set_kpoints(kpoints) self.assertEqual( np.abs(kpt.get_kpoints() - np.array(kpoints)).sum(), 0.) self.assertEqual( np.abs( kpt.get_kpoints(cartesian=True) - np.array(cartesian_kpoints)).sum(), 0.) # Check also after storing kpt.store() kpt2 = load_node(kpt.pk) self.assertEqual( np.abs(kpt2.get_kpoints() - np.array(kpoints)).sum(), 0.) self.assertEqual( np.abs( kpt2.get_kpoints(cartesian=True) - np.array(cartesian_kpoints)).sum(), 0.)
def reuse_kpoints_grid(grid, lowest_pk=False): """ Retrieve previously stored kpoints mesh data node. If there is no such ``KpointsData``, a new node will be created. Will return the one with highest pk :param grid: Grid to be retrieved :param bool lowest_pk: If set to True will return the node with lowest pk :returns: A KpointsData node representing the grid requested """ from aiida.orm import QueryBuilder from aiida.orm import KpointsData qbd = QueryBuilder() qbd.append(KpointsData, tag="kpoints", filters={ "attributes.mesh.0": grid[0], "attributes.mesh.1": grid[1], "attributes.mesh.2": grid[2] }) if lowest_pk: order = "asc" else: order = "desc" qbd.order_by({"kpoints": [{"id": {"order": order}}]}) if qbd.count() >= 1: return qbd.first()[0] kpoints = KpointsData() kpoints.set_kpoints_mesh(grid) return kpoints
def get_shear_relax_builder(self, shear_strain_ratio: float, additional_relax_pks: list = None): """ Get relax builder for shear introduced relax twinboundary structure. Args: shear_strain_ratio (float): shear strain ratio """ twinboundary_analyzer = self.get_twinboundary_analyzer( additional_relax_pks=additional_relax_pks) cell = twinboundary_analyzer.get_shear_cell( shear_strain_ratio=shear_strain_ratio, is_standardize=False) # in order to get rotation matrix std = StandardizeCell(cell=cell) std_cell = std.get_standardized_cell(to_primitive=True, no_idealize=False, no_sort=True) if additional_relax_pks is None: rlx_pk = self.get_pks()['relax_pk'] else: rlx_pk = additional_relax_pks[-1] rlx_node = load_node(rlx_pk) builder = rlx_node.get_builder_restart() # fix kpoints mesh, offset = map(np.array, builder.kpoints.get_kpoints_mesh()) orig_mesh = np.abs( np.dot(np.linalg.inv(self._standardize.transformation_matrix), mesh).astype(int)) orig_offset = np.round(np.abs( np.dot(np.linalg.inv(std.transformation_matrix), offset)), decimals=2) std_mesh = np.abs( np.dot(std.transformation_matrix, orig_mesh).astype(int)) std_offset = np.round(np.abs( np.dot(std.transformation_matrix, orig_offset)), decimals=2) kpt = KpointsData() kpt.set_kpoints_mesh(std_mesh, offset=std_offset) builder.kpoints = kpt # fix structure builder.structure = get_aiida_structure(cell=std_cell) # fix relax conf builder.relax.convergence_max_iterations = Int(100) builder.relax.positions = Bool(True) builder.relax.shape = Bool(False) builder.relax.volume = Bool(False) builder.relax.convergence_positions = Float(1e-4) builder.relax.force_cutoff = \ Float(AiidaRelaxWorkChain(node=rlx_node).get_max_force()) builder.metadata.label = "tbr:{} rlx:{} shr:{} std:{}".format( self._pk, rlx_node.pk, shear_strain_ratio, True) builder.metadata.description = \ "twinboundary_relax_pk:{} relax_pk:{} " \ "shear_strain_ratio:{} standardize:{}".format( self._pk, rlx_node.pk, shear_strain_ratio, True) return builder
def test_bandsexport_single_kp(self): """ Plot band for single k-point (issue #2462). """ kpnts = KpointsData() kpnts.set_kpoints([[0., 0., 0.]]) bands = BandsData() bands.set_kpointsdata(kpnts) bands.set_bands([[1.0, 2.0]]) bands.store() # matplotlib options = [str(bands.id), '--format', 'mpl_singlefile'] res = self.cli_runner.invoke(cmd_bands.bands_export, options, catch_exceptions=False) self.assertIn( b'p.scatter', res.stdout_bytes, 'The string p.scatter was not found in the bands mpl export') # gnuplot with self.cli_runner.isolated_filesystem(): options = [str(bands.id), '--format', 'gnuplot', '-o', 'bands.gnu'] self.cli_runner.invoke(cmd_bands.bands_export, options, catch_exceptions=False) with open('bands.gnu', 'r') as gnu_file: res = gnu_file.read() self.assertIn( 'vectors nohead', res, 'The string "vectors nohead" was not found in the gnuplot script' )
def validate_kpoints_mesh(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 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 """ # pylint: disable=unused-argument from aiida.orm import KpointsData if not value: return None if any([not isinstance(integer, int) for integer 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
def _generate_kpoints_mesh(npoints): """Return a `KpointsData` with a mesh of npoints in each direction.""" from aiida.orm import KpointsData kpoints = KpointsData() kpoints.set_kpoints_mesh([npoints] * 3) return kpoints
def test_fleurinp_modifier_set_kpointsdata(create_fleurinp): """Test if setting a kpoints list to a fleurinp data node works""" from aiida.orm import KpointsData fleurinp_tmp = create_fleurinp(inpxmlfilefolder) fleurinp_tmp.store() # needed? struc = fleurinp_tmp.get_structuredata_ncf() kps = KpointsData() kps.set_cell(struc.cell) kps.pbc = struc.pbc kpoints_pos = [[0.0, 0.0, 0.0], [0.0, 0.5, 0.0], [0.5, 0.0, 0.0], [0.5, 0.0, 0.5], [0.5, 0.5, 0.5], [1.0, 1.0, 1.0]] kpoints_weight = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0] # Fleur renormalizes kps.set_kpoints(kpoints_pos, cartesian=False, weights=kpoints_weight) kps.store() # needed, because node has to be loaded... #print(fleurinp_tmp) fm = FleurinpModifier(fleurinp_tmp) fm.set_kpointsdata(kps) fm.show(validate=True, display=False) fm.freeze() # check if kpoint node is input into modification # uuid of node show also work fm = FleurinpModifier(fleurinp_tmp) fm.set_kpointsdata(kps.uuid) fm.freeze()
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 _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( # pylint: disable=unbalanced-tuple-unpacking 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': Dict(dict=parameters), 'explicit_kpoints': kpoints}
def updater(calc_dict, inp_to_update, parameters): variables = parameters[0] new_values = parameters[1] if variables == 'kpoint_mesh' or variables == 'kpoint_density': k_quantity = new_values inp_to_update.scf.kpoints = KpointsData() inp_to_update.scf.kpoints.set_cell_from_structure( inp_to_update.scf.pw.structure) #to count the PBC... if isinstance(k_quantity, tuple): inp_to_update.scf.kpoints.set_kpoints_mesh(k_quantity[0], k_quantity[1]) else: inp_to_update.scf.kpoints.set_kpoints_mesh_from_density( 1 / k_quantity, force_parity=True) inp_to_update.nscf.kpoints = inp_to_update.scf.kpoints try: inp_to_update.parent_folder = find_pw_parent( take_calc_from_remote(inp_to_update.parent_folder), calc_type=['scf']).outputs.remote_folder #I need to start from the scf calc except: del inp_to_update.parent_folder #do all scf+nscf+y in case inp_to_update.yres.yambo.settings = update_dict( inp_to_update.yres.yambo.settings, 'COPY_SAVE', False) #no yambo here inp_to_update.yres.yambo.settings = update_dict( inp_to_update.yres.yambo.settings, 'COPY_DBS', False) #no yambo here value = k_quantity elif isinstance(variables, list): #general new_params = inp_to_update.yres.yambo.parameters.get_dict() for i in variables: new_params[i] = new_values[variables.index(i)] inp_to_update.yres.yambo.parameters = Dict(dict=new_params) value = new_values elif isinstance(variables, str): #general new_params = inp_to_update.yres.yambo.parameters.get_dict() if isinstance(new_values, list): new_params[variables] = new_values[0] else: new_params[variables] = new_values inp_to_update.yres.yambo.parameters = Dict(dict=new_params) value = new_values return inp_to_update, value
def wf_getkpoints(aiida_structure, kptper_recipang): from aiida.orm import KpointsData def get_kmeshfrom_kptper_recipang(aiida_structure, kptper_recipang): import numpy as np kptper_recipang = kptper_recipang.value ase_structure = aiida_structure.get_ase() reci_cell = ase_structure.get_reciprocal_cell() kmesh = [np.ceil(kptper_recipang * np.linalg.norm(reci_cell[i])) for i in range(len(reci_cell))] return kmesh kpoints_mesh = get_kmeshfrom_kptper_recipang(aiida_structure, kptper_recipang) kpoints = KpointsData() kpoints.set_kpoints_mesh(kpoints_mesh) 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 _generate_inputdata(self, parameters: orm.Dict, pseudos, structure: orm.StructureData, kpoints: orm.KpointsData) -> ty.Tuple[str, list]: """Generate the input file content and list of pseudopotential files to copy. :param parameters: input parameters Dict :param pseudos: pseudopotential input namespace :param structure: input structure :param kpoints: input kpoints :returns: input file content, pseudopotential copy list """ local_copy_pseudo_list = [] # abipy has its own subclass of Pymatgen's `Structure`, so we use that pmg_structure = structure.get_pymatgen() abi_structure = AbiStructure.as_structure(pmg_structure) abi_structure = abi_structure.abi_sanitize(primitive=True) for kind in structure.get_kind_names(): pseudo = pseudos[kind] local_copy_pseudo_list.append((pseudo.uuid, pseudo.filename, f'{self._PSEUDO_SUBFOLDER}{pseudo.filename}')) # Pseudopotentials _must_ be listed in the same order as 'znucl' in the input file. # So, we need to get 'znucl' as abipy will write it then construct the appropriate 'pseudos' string. znucl = structure_to_abivars(abi_structure)['znucl'] ordered_pseudo_filenames = [pseudos[constants.elements[Z]['symbol']].filename for Z in znucl] pseudo_parameters = { 'pseudos': '"' + ', '.join(ordered_pseudo_filenames) + '"', 'pp_dirpath': f'"{self._PSEUDO_SUBFOLDER}"' } input_parameters = parameters.get_dict() # k-points are provided to abipy separately from the main input parameters, so we pop out # parameters related to the k-points shiftk = input_parameters.pop('shiftk', [0.0, 0.0, 0.0]) # NOTE: currently, only k-point mesh are supported, not k-point paths kpoints_mesh = kpoints.get_kpoints_mesh()[0] # use abipy to write the input file input_parameters = {**input_parameters, **pseudo_parameters} # give abipy the HGH_TABLE only so it won't error, but don't actually print these to file abi_input = AbinitInput( structure=abi_structure, pseudos=HGH_TABLE, abi_kwargs=input_parameters ) abi_input.set_kmesh( ngkpt=kpoints_mesh, shiftk=shiftk ) return abi_input.to_string(with_pseudos=False), local_copy_pseudo_list
def updater(self, inp_to_update, k_distance, first): #parameter list? yambopy philosophy if self.var == 'bands': new_params = inp_to_update.yres.gw.parameters.get_dict() new_params['BndsRnXp'][ -1] = new_params['BndsRnXp'][-1] + self.delta * first new_params['GbndRnge'][ -1] = new_params['GbndRnge'][-1] + self.delta * first inp_to_update.yres.gw.parameters = Dict(dict=new_params) value = new_params['GbndRnge'][-1] elif self.var == 'kpoints': k_distance = k_distance + self.delta * first inp_to_update.scf.kpoints = KpointsData() inp_to_update.scf.kpoints.set_cell( inp_to_update.scf.pw.structure.cell) inp_to_update.scf.kpoints.set_kpoints_mesh_from_density( 1 / k_distance, force_parity=True) inp_to_update.nscf.kpoints = inp_to_update.scf.kpoints try: del inp_to_update.parent_folder #I need to start from scratch... except: pass value = k_distance elif self.var == 'cutoff': new_params = inp_to_update.yres.gw.parameters.get_dict() new_params['CUTBox'] = new_params['CUTBox'] + [ 1, 1, 1 ] * self.delta * first inp_to_update.yres.gw.parameters = Dict(dict=new_params) value = new_params['CUTBox'][-1] else: #"scalar" quantity new_params = inp_to_update.yres.gw.parameters.get_dict() new_params[str( self.var)] = new_params[str(self.var)] + self.delta * first inp_to_update.yres.gw.parameters = Dict(dict=new_params) value = new_params[str(self.var)] return inp_to_update, value
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 example_dft(code, pseudo_family): """Run simple silicon DFT calculation.""" print('Testing Abinit Total energy on Silicon using AbinitCalculation') thisdir = os.path.dirname(os.path.realpath(__file__)) structure = StructureData(pymatgen=mg.core.Structure.from_file( os.path.join(thisdir, 'files', 'Si.cif'))) pseudo_family = Group.objects.get(label=pseudo_family) pseudos = pseudo_family.get_pseudos(structure=structure) kpoints = KpointsData() kpoints.set_cell_from_structure(structure) kpoints.set_kpoints_mesh([2, 2, 2]) # kpoints.set_kpoints_mesh_from_density(2.0) parameters_dict = { 'code': code, 'structure': structure, 'pseudos': pseudos, 'kpoints': kpoints, 'parameters': Dict( dict={ 'ecut': 8.0, # Maximal kinetic energy cut-off, in Hartree 'nshiftk': 4, # of the reciprocal space (that form a BCC lattice !) 'shiftk': [[0.5, 0.5, 0.5], [0.5, 0.0, 0.0], [0.0, 0.5, 0.0], [0.0, 0.0, 0.5]], 'nstep': 20, # Maximal number of SCF cycles 'toldfe': 1.0e-6, # Will stop when, twice in a row, the difference # between two consecutive evaluations of total energy # differ by less than toldfe (in Hartree) }), 'metadata': { 'options': { 'withmpi': True, 'max_wallclock_seconds': 2 * 60, 'resources': { 'num_machines': 1, 'num_mpiprocs_per_machine': 4, } } } } print('Running calculation...') run(AbinitCalculation, **parameters_dict)
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 test_reciprocal_cell(self): """ Test the `reciprocal_cell` method. This is a regression test for #2749. """ kpt = KpointsData() kpt.set_cell_from_structure(self.structure) self.assertEqual(np.abs(kpt.reciprocal_cell - self.expected_reciprocal_cell).sum(), 0.) # Check also after storing kpt.store() kpt2 = load_node(kpt.pk) self.assertEqual(np.abs(kpt2.reciprocal_cell - self.expected_reciprocal_cell).sum(), 0.)
def kpt_crop(kpoints: orm.KpointsData, centers: orm.ArrayData, radii: orm.ArrayData, anticrop: orm.Bool) -> orm.KpointsData: kpt_cryst = kpoints.get_kpoints_mesh(print_list=True) cell = kpoints.cell recipr = recipr_base(cell) centers = centers.get_array('centers') centers = centers.dot(recipr) radii = radii.get_array('radii') kpt, wgt = _kpt_crop(kpt_cryst, recipr, centers=centers, radii=radii, anticrop=anticrop.value) res = orm.KpointsData() res.set_cell(cell) res.set_kpoints(kpt, cartesian=True, weights=wgt) return res
def connect_structure_bands(strct): # pylint: disable=unused-argument alat = 4. cell = np.array([ [alat, 0., 0.], [0., alat, 0.], [0., 0., alat], ]) kpnts = KpointsData() kpnts.set_cell(cell) kpnts.set_kpoints([[0., 0., 0.], [0.1, 0.1, 0.1]]) bands = BandsData() bands.set_kpointsdata(kpnts) bands.set_bands([[1.0, 2.0], [3.0, 4.0]]) return bands
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([[0., 0., 0.], [0.1, 0.1, 0.1]]) b = BandsData() b.set_kpointsdata(k) b.set_bands([[1.0, 2.0], [3.0, 4.0]]) return b
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)
'Solution-method': 'diagon', 'electronic-temperature': '25 meV', 'write-forces': True, }) #The basis set basis = Dict( dict={ 'pao-energy-shift': '300 meV', '%block pao-basis-sizes': """ Si DZP %endblock pao-basis-sizes""", }) #The kpoints kpoints = KpointsData() kpoints.set_kpoints_mesh([4, 4, 4]) #The pseudopotentials pseudos_dict = {} raw_pseudos = [("Si.psf", ['Si'])] for fname, kinds in raw_pseudos: absname = op.realpath(op.join(op.dirname(__file__), "../fixtures/sample_psf", fname)) pseudo = PsfData.get_or_create(absname) if not pseudo.is_stored: print("\nCreated the pseudo for {}".format(kinds)) else: print("\nUsing the pseudo for {} from DB: {}".format(kinds, pseudo.pk)) for j in kinds: pseudos_dict[j]=pseudo
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 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 Dict, 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 """ # pylint: disable=too-many-locals from aiida.tools.data.structure import spglib_tuple_to_structure, structure_to_spglib_tuple 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_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'] = Dict(dict=rawdict) result['explicit_kpoints'] = kpoints result['primitive_structure'] = primitive_structure result['conv_structure'] = conv_structure return result
def test_inp_gen_cell(gen_instance, sto_calc_inputs): """ Test generation of the inputs """ gen_instance.inputs = sto_calc_inputs gen_instance.prepare_inputs() assert 'symmetry_generate' in gen_instance.cell_file assert "POSITIONS_ABS" in gen_instance.cell_file assert "LATTICE_CART" in gen_instance.cell_file assert isinstance(gen_instance.cell_file["cell_constraints"], list) assert 'C9' in gen_instance.cell_file['SPECIES_POT'][0] # Test extra-kpoints from aiida.orm import KpointsData kpn1 = KpointsData() kpn1.set_kpoints_mesh((4, 4, 4)) gen_instance._include_extra_kpoints(kpn1, 'phonon', { 'task': ('phonon', ), 'need_weights': False }) assert 'phonon_kpoint_mp_grid' in gen_instance.cell_file kpn1.set_kpoints_mesh(( 4, 4, 4, ), (0.25, 0.25, 0.25)) gen_instance._include_extra_kpoints(kpn1, 'phonon', { 'task': ('phonon', ), 'need_weights': False }) assert 'phonon_kpoint_mp_offset' in gen_instance.cell_file # Explicit kpoints, with/without the weights kpn2 = KpointsData() kpn_points = [[0, 0, 0], [0.5, 0.5, 0.5]] kpn_weights = [0.3, 0.6] kpn2.set_kpoints(kpn_points, weights=kpn_weights) gen_instance._include_extra_kpoints(kpn2, 'bs', { 'task': ('bandstructure', ), 'need_weights': True }) assert len(gen_instance.cell_file['BS_KPOINT_LIST'][0].split()) == 4 kpn2 = KpointsData() kpn_points = [[0, 0, 0], [0.5, 0.5, 0.5]] kpn2.set_kpoints(kpn_points) gen_instance._include_extra_kpoints(kpn2, 'bs', { 'task': ('bandstructure', ), 'need_weights': True }) assert len(gen_instance.cell_file['BS_KPOINT_LIST'][0].split()) == 4 assert float(gen_instance.cell_file['BS_KPOINT_LIST'][0].split()[3]) == 0.5 # No weights gen_instance._include_extra_kpoints(kpn2, 'bs', { 'task': ('bandstructure', ), 'need_weights': False }) assert len(gen_instance.cell_file['BS_KPOINT_LIST'][0].split()) == 3 assert 'BS_KPOINT_LIST' in gen_instance.cell_file
def get_kpointsdata_ncf(self, name=None, index=None, only_used=False): """ This routine returns an AiiDA :class:`~aiida.orm.KpointsData` type produced from the ``inp.xml`` file. This only works if the kpoints are listed in the in inpxml. This is NOT a calcfunction and does not keep the provenance! :param name: str, optional, if given only the kpoint set with the given name is returned :param index: int, optional, if given only the kpoint set with the given index is returned :returns: :class:`~aiida.orm.KpointsData` node """ from aiida.orm import KpointsData from masci_tools.util.xml.xml_getters import get_kpoints_data # HINT, TODO:? in this routine, the 'cell' you might get in an other way # exp: StructureData.cell, but for this you have to make a structureData Node, # which might take more time for structures with lots of atoms. # then just parsing the cell from the inp.xml # as in the routine get_structureData xmltree, schema_dict = self.load_inpxml() if name is None and index is None: kpoints, weights, cell, pbc = get_kpoints_data(xmltree, schema_dict, only_used=only_used) else: kpoints, weights, cell, pbc = get_kpoints_data(xmltree, schema_dict, name=name, index=index, only_used=only_used) if isinstance(kpoints, dict): kpoints_data = {} for (label, kpoints_set), weights_set in zip(kpoints.items(), weights.values()): kps = KpointsData() kps.set_cell(cell) kps.pbc = pbc kps.set_kpoints(kpoints_set, cartesian=False, weights=weights_set) #kpoints_data.add_link_from(self, label='fleurinp.kpts', link_type=LinkType.CREATE) kps.label = 'fleurinp.kpts' kpoints_data[label] = kps else: kpoints_data = KpointsData() kpoints_data.set_cell(cell) kpoints_data.pbc = pbc kpoints_data.set_kpoints(kpoints, cartesian=False, weights=weights) #kpoints_data.add_link_from(self, label='fleurinp.kpts', link_type=LinkType.CREATE) kpoints_data.label = 'fleurinp.kpts' return kpoints_data
def get_explicit_kpoints(kpoints): """Convert from a mesh to an explicit list""" from aiida.orm import KpointsData kpt = KpointsData() kpt.set_kpoints(kpoints.get_kpoints_mesh(print_list=True)) return kpt
pw_code = load_code("<CODE LABEL>") # Replace with the QE pw.x code label wannier_code = load_code( "<CODE LABEL>") # Replace with the Wannier90 wannier.x code label pw2wannier90_code = load_code( "<CODE LABEL>") # Replace with the QE pw2wannier90.x code label pseudo_family_name = "<UPF FAMILY NAME>" # Replace with the name of the pseudopotential family for SSSP efficiency # GaAs structure a = 5.68018817933178 # angstrom structure = StructureData( cell=[[-a / 2., 0, a / 2.], [0, a / 2., a / 2.], [-a / 2., a / 2., 0]]) structure.append_atom(symbols=['Ga'], position=(0., 0., 0.)) structure.append_atom(symbols=['As'], position=(-a / 4., a / 4., a / 4.)) # 4x4x4 k-points mesh for the SCF kpoints_scf = KpointsData() kpoints_scf.set_kpoints_mesh([4, 4, 4]) # 10x10x10 k-points mesh for the NSCF/Wannier90 calculations kpoints_nscf = KpointsData() kpoints_nscf.set_kpoints_mesh([10, 10, 10]) # k-points path for the band structure kpoint_path = Dict( dict={ 'point_coords': { 'GAMMA': [0.0, 0.0, 0.0], 'K': [0.375, 0.375, 0.75], 'L': [0.5, 0.5, 0.5], 'U': [0.625, 0.25, 0.625], 'W': [0.5, 0.25, 0.75],
def launch_calculation(code, structure, pseudo_family, kpoints_mesh, ecutwfc, ecutrho, hubbard_u, hubbard_v, hubbard_file_pk, starting_magnetization, smearing, max_num_machines, max_wallclock_seconds, with_mpi, daemon, parent_folder, dry_run, mode, unfolded_kpoints): """Run a PwCalculation.""" from aiida.orm import Dict, KpointsData from aiida.plugins import CalculationFactory from aiida_quantumespresso.utils.resources import get_default_options cutoff_wfc, cutoff_rho = pseudo_family.get_recommended_cutoffs( structure=structure, unit='Ry') parameters = { 'CONTROL': { 'calculation': mode, }, 'SYSTEM': { 'ecutwfc': ecutwfc or cutoff_wfc, 'ecutrho': ecutrho or cutoff_rho, } } if mode in CALCS_REQUIRING_PARENT and not parent_folder: raise click.BadParameter( f"calculation '{mode}' requires a parent folder", param_hint='--parent-folder') try: hubbard_file = validate.validate_hubbard_parameters( structure, parameters, hubbard_u, hubbard_v, hubbard_file_pk) except ValueError as exception: raise click.BadParameter(str(exception)) try: validate.validate_starting_magnetization(structure, parameters, starting_magnetization) except ValueError as exception: raise click.BadParameter(str(exception)) try: validate.validate_smearing(parameters, smearing) except ValueError as exception: raise click.BadParameter(str(exception)) if unfolded_kpoints: unfolded_list = kpoints_mesh.get_kpoints_mesh(print_list=True) kpoints_mesh = KpointsData() kpoints_mesh.set_kpoints(unfolded_list) inputs = { 'code': code, 'structure': structure, 'pseudos': pseudo_family.get_pseudos(structure=structure), 'kpoints': kpoints_mesh, 'parameters': Dict(dict=parameters), 'metadata': { 'options': get_default_options(max_num_machines, max_wallclock_seconds, with_mpi), } } if parent_folder: inputs['parent_folder'] = parent_folder if hubbard_file: inputs['hubbard_file'] = hubbard_file if dry_run: if daemon: # .submit() would forward to .run(), but it's better to stop here, # since it's a bit unexpected and the log messages output to screen # would be confusing ("Submitted PwCalculation<None> to the daemon") raise click.BadParameter( 'cannot send to the daemon if in dry_run mode', param_hint='--daemon') inputs['metadata']['store_provenance'] = False inputs['metadata']['dry_run'] = True launch.launch_process(CalculationFactory('quantumespresso.pw'), daemon, **inputs)