def get_gsinput_alas_ngkpt(ngkpt, usepaw=0, as_task=False): """ Build and return a GS input file for AlAs or a Task if `as_task` """ if usepaw != 0: raise NotImplementedError("PAW") pseudos = abidata.pseudos("13al.981214.fhi", "33as.pspnc") structure = abidata.structure_from_ucell("AlAs") from abipy.abio.inputs import AbinitInput scf_input = AbinitInput(structure, pseudos=pseudos) scf_input.set_vars( nband=5, ecut=8.0, ngkpt=ngkpt, nshiftk=1, shiftk=[0, 0, 0], tolvrs=1.0e-6, diemac=12.0, ) if not as_task: return scf_input else: from abipy.flowtk.tasks import ScfTask return ScfTask(scf_input)
def scf_input(structure, pseudos, kppa=None, ecut=None, pawecutdg=None, nband=None, accuracy="normal", spin_mode="polarized", smearing="fermi_dirac:0.1 eV", charge=0.0, scf_algorithm=None, shift_mode="Monkhorst-Pack"): structure = Structure.as_structure(structure) abinit_input = AbinitInput(structure, pseudos) # Set the cutoff energies. abinit_input.set_vars(_find_ecut_pawecutdg(ecut, pawecutdg, abinit_input.pseudos)) # SCF calculation. kppa = _DEFAULTS.get("kppa") if kppa is None else kppa shifts = (0.5, 0.5, 0.5) if shift_mode[0].lower() == "m" else (0.0, 0.0, 0.0) scf_ksampling = aobj.KSampling.automatic_density(structure, kppa, chksymbreak=0, shifts=shifts) scf_electrons = aobj.Electrons(spin_mode=spin_mode, smearing=smearing, algorithm=scf_algorithm, charge=charge, nband=nband, fband=None) if spin_mode=="polarized": abinit_input.set_autospinat() if scf_electrons.nband is None: scf_electrons.nband = _find_scf_nband(structure, abinit_input.pseudos, scf_electrons,abinit_input.get('spinat', None)) abinit_input.set_vars(scf_ksampling.to_abivars()) abinit_input.set_vars(scf_electrons.to_abivars()) abinit_input.set_vars(_stopping_criterion("scf", accuracy)) return abinit_input
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 get_gsinput_si(usepaw=0, as_task=False): # Build GS input file. pseudos = abidata.pseudos("14si.pspnc") if usepaw == 0 else data.pseudos("Si.GGA_PBE-JTH-paw.xml") #silicon = abilab.Structure.zincblende(5.431, ["Si", "Si"], units="ang") silicon = abidata.cif_file("si.cif") from abipy.abio.inputs import AbinitInput scf_input = AbinitInput(silicon, pseudos) ecut = 6 scf_input.set_vars( ecut=ecut, pawecutdg=40, nband=6, paral_kgb=0, iomode=3, toldfe=1e-9, ) if usepaw: scf_input.set_vars(pawecutdg=4 * ecut) # K-point sampling (shifted) scf_input.set_autokmesh(nksmall=4) if not as_task: return scf_input else: from abipy.flowtk.tasks import ScfTask return ScfTask(scf_input)
def get_gsinput_si(usepaw=0, as_task=False): """ Build and return a GS input file for silicon or a Task if `as_task` """ pseudos = abidata.pseudos( "14si.pspnc") if usepaw == 0 else abidata.pseudos( "Si.GGA_PBE-JTH-paw.xml") silicon = abidata.cif_file("si.cif") from abipy.abio.inputs import AbinitInput scf_input = AbinitInput(silicon, pseudos) ecut = 6 scf_input.set_vars( ecut=ecut, nband=6, paral_kgb=0, iomode=3, toldfe=1e-9, ) if usepaw: scf_input.set_vars(pawecutdg=4 * ecut) # K-point sampling (shifted) scf_input.set_autokmesh(nksmall=4) if not as_task: return scf_input else: from abipy.flowtk.tasks import ScfTask return ScfTask(scf_input)
def json_read_abinit_input_from_path(json_path): """ Read a json file from the absolute path ``json_path``, return |AbinitInput| instance. """ from abipy.abio.inputs import AbinitInput with open(json_path, "rt") as fh: d = json.load(fh) # Convert pseudo paths: extract basename and build path in abipy/data/pseudos. for pdict in d["pseudos"]: pdict["filepath"] = os.path.join(abidata.dirpath, "pseudos", os.path.basename(pdict["filepath"])) return AbinitInput.from_dict(d)
def scf_piezo_elastic_inputs(structure, pseudos, kppa, ecut=None, pawecutdg=None, scf_nband=None, accuracy="normal", spin_mode="polarized", smearing="fermi_dirac:0.1 eV", charge=0.0, scf_algorithm=None, ddk_tol=None, rf_tol=None): """ Returns a :class:`AbinitInput` for performing elastic and piezoelectric constants calculations. GS input + the input files for the elastic and piezoelectric constants calculation. Args: structure: :class:`Structure` object. pseudos: List of filenames or list of :class:`Pseudo` objects or :class:`PseudoTable` object. kppa: Defines the sampling used for the SCF run. ecut: cutoff energy in Ha (if None, ecut is initialized from the pseudos according to accuracy) pawecutdg: cutoff energy in Ha for PAW double-grid (if None, pawecutdg is initialized from the pseudos according to accuracy) scf_nband: Number of bands for SCF run. If scf_nband is None, nband is automatically initialized from the list of pseudos, the structure and the smearing option. accuracy: Accuracy of the calculation. spin_mode: Spin polarization. smearing: Smearing technique. charge: Electronic charge added to the unit cell. scf_algorithm: Algorithm used for solving of the SCF cycle. ddk_tol """ # Build the input file for the GS run. gs_inp = AbinitInput(structure=structure, pseudos=pseudos) # Set the cutoff energies. gs_inp.set_vars(_find_ecut_pawecutdg(ecut, pawecutdg, gs_inp.pseudos)) ksampling = aobj.KSampling.automatic_density(gs_inp.structure, kppa, chksymbreak=0, shifts=(0.0, 0.0, 0.0)) gs_inp.set_vars(ksampling.to_abivars()) gs_inp.set_vars(tolvrs=1.0e-18) scf_electrons = aobj.Electrons(spin_mode=spin_mode, smearing=smearing, algorithm=scf_algorithm, charge=charge, nband=None, fband=None) if scf_electrons.nband is None: scf_electrons.nband = _find_scf_nband(structure, gs_inp.pseudos, scf_electrons) gs_inp.set_vars(scf_electrons.to_abivars()) all_inps = [gs_inp] # Add the ddk input ddk_inp = gs_inp.deepcopy() ddk_inp.set_vars( rfelfd=2, # Activate the calculation of the d/dk perturbation rfdir=(1,1,1), # All directions nqpt=1, # One wavevector is to be considered qpt=(0, 0, 0), # q-wavevector. kptopt=2, # Take into account time-reversal symmetry. iscf=-3, # The d/dk perturbation must be treated in a non-self-consistent way ) if ddk_tol is None: ddk_tol = {"tolwfr": 1.0e-20} if len(ddk_tol) != 1 or any(k not in _tolerances for k in ddk_tol): raise ValueError("Invalid tolerance: {}".format(ddk_tol)) ddk_inp.pop_tolerances() ddk_inp.set_vars(ddk_tol) ddk_inp.add_tags(DDK) all_inps.append(ddk_inp) # Add the Response Function calculation rf_inp = gs_inp.deepcopy() rf_inp.set_vars(rfphon=1, # Atomic displacement perturbation rfatpol=(1,len(gs_inp.structure)), # Perturbation of all atoms rfstrs=3, # Do the strain perturbations rfdir=(1,1,1), # All directions nqpt=1, # One wavevector is to be considered qpt=(0, 0, 0), # q-wavevector. kptopt=2, # Take into account time-reversal symmetry. iscf=7, # The d/dk perturbation must be treated in a non-self-consistent way ) if rf_tol is None: rf_tol = {"tolvrs": 1.0e-12} if len(rf_tol) != 1 or any(k not in _tolerances for k in rf_tol): raise ValueError("Invalid tolerance: {}".format(rf_tol)) rf_inp.pop_tolerances() rf_inp.set_vars(rf_tol) rf_inp.add_tags([DFPT, STRAIN]) all_inps.append(rf_inp) return MultiDataset.from_inputs(all_inps)
def scf_phonons_inputs(structure, pseudos, kppa, ecut=None, pawecutdg=None, scf_nband=None, accuracy="normal", spin_mode="polarized", smearing="fermi_dirac:0.1 eV", charge=0.0, scf_algorithm=None): """ Returns a :class:`AbinitInput` for performing phonon calculations. GS input + the input files for the phonon calculation. Args: structure: :class:`Structure` object. pseudos: List of filenames or list of :class:`Pseudo` objects or :class:`PseudoTable` object. kppa: Defines the sampling used for the SCF run. ecut: cutoff energy in Ha (if None, ecut is initialized from the pseudos according to accuracy) pawecutdg: cutoff energy in Ha for PAW double-grid (if None, pawecutdg is initialized from the pseudos according to accuracy) scf_nband: Number of bands for SCF run. If scf_nband is None, nband is automatically initialized from the list of pseudos, the structure and the smearing option. accuracy: Accuracy of the calculation. spin_mode: Spin polarization. smearing: Smearing technique. charge: Electronic charge added to the unit cell. scf_algorithm: Algorithm used for solving of the SCF cycle. """ # Build the input file for the GS run. gs_inp = AbinitInput(structure=structure, pseudos=pseudos) # Set the cutoff energies. gs_inp.set_vars(_find_ecut_pawecutdg(ecut, pawecutdg, gs_inp.pseudos)) ksampling = aobj.KSampling.automatic_density(gs_inp.structure, kppa, chksymbreak=0) gs_inp.set_vars(ksampling.to_abivars()) gs_inp.set_vars(tolvrs=1.0e-18) # Get the qpoints in the IBZ. Note that here we use a q-mesh with ngkpt=(4,4,4) and shiftk=(0,0,0) # i.e. the same parameters used for the k-mesh in gs_inp. qpoints = gs_inp.abiget_ibz(ngkpt=(4,4,4), shiftk=(0,0,0), kptopt=1).points #print("get_ibz qpoints:", qpoints) # Build the input files for the q-points in the IBZ. ph_inputs = MultiDataset(gs_inp.structure, pseudos=gs_inp.pseudos, ndtset=len(qpoints)) for ph_inp, qpt in zip(ph_inputs, qpoints): # Response-function calculation for phonons. ph_inp.set_vars( rfphon=1, # Will consider phonon-type perturbation nqpt=1, # One wavevector is to be considered qpt=qpt, # This wavevector is q=0 (Gamma) tolwfr=1.0e-20, kptopt=3, # One could used symmetries for Gamma. ) #rfatpol 1 1 # Only the first atom is displaced #rfdir 1 0 0 # Along the first reduced coordinate axis #kptopt 2 # Automatic generation of k points, taking irred_perts = ph_inp.abiget_irred_phperts() #for pert in irred_perts: # #print(pert) # # TODO this will work for phonons, but not for the other types of perturbations. # ph_inp = q_inp.deepcopy() # rfdir = 3 * [0] # rfdir[pert.idir -1] = 1 # ph_inp.set_vars( # rfdir=rfdir, # rfatpol=[pert.ipert, pert.ipert] # ) # ph_inputs.append(ph_inp) # Split input into gs_inp and ph_inputs all_inps = [gs_inp] all_inps.extend(ph_inputs.split_datasets()) return all_inps
def scf_phonons_inputs(structure, pseudos, kppa, ecut=None, pawecutdg=None, scf_nband=None, accuracy="normal", spin_mode="polarized", smearing="fermi_dirac:0.1 eV", charge=0.0, scf_algorithm=None): """ Returns a :class:`AbinitInput` for performing phonon calculations. GS input + the input files for the phonon calculation. Args: structure: :class:`Structure` object. pseudos: List of filenames or list of :class:`Pseudo` objects or :class:`PseudoTable` object. kppa: Defines the sampling used for the SCF run. ecut: cutoff energy in Ha (if None, ecut is initialized from the pseudos according to accuracy) pawecutdg: cutoff energy in Ha for PAW double-grid (if None, pawecutdg is initialized from the pseudos according to accuracy) scf_nband: Number of bands for SCF run. If scf_nband is None, nband is automatically initialized from the list of pseudos, the structure and the smearing option. accuracy: Accuracy of the calculation. spin_mode: Spin polarization. smearing: Smearing technique. charge: Electronic charge added to the unit cell. scf_algorithm: Algorithm used for solving of the SCF cycle. """ # Build the input file for the GS run. gs_inp = AbinitInput(structure=structure, pseudos=pseudos) # Set the cutoff energies. gs_inp.set_vars(_find_ecut_pawecutdg(ecut, pawecutdg, gs_inp.pseudos)) ksampling = aobj.KSampling.automatic_density(gs_inp.structure, kppa, chksymbreak=0) gs_inp.set_vars(ksampling.to_abivars()) gs_inp.set_vars(tolvrs=1.0e-18) # Get the qpoints in the IBZ. Note that here we use a q-mesh with ngkpt=(4,4,4) and shiftk=(0,0,0) # i.e. the same parameters used for the k-mesh in gs_inp. qpoints = gs_inp.abiget_ibz(ngkpt=(4, 4, 4), shiftk=(0, 0, 0), kptopt=1).points #print("get_ibz qpoints:", qpoints) # Build the input files for the q-points in the IBZ. ph_inputs = MultiDataset(gs_inp.structure, pseudos=gs_inp.pseudos, ndtset=len(qpoints)) for ph_inp, qpt in zip(ph_inputs, qpoints): # Response-function calculation for phonons. ph_inp.set_vars( rfphon=1, # Will consider phonon-type perturbation nqpt=1, # One wavevector is to be considered qpt=qpt, # This wavevector is q=0 (Gamma) tolwfr=1.0e-20, kptopt=3, # One could used symmetries for Gamma. ) #rfatpol 1 1 # Only the first atom is displaced #rfdir 1 0 0 # Along the first reduced coordinate axis #kptopt 2 # Automatic generation of k points, taking irred_perts = ph_inp.abiget_irred_phperts() #for pert in irred_perts: # #print(pert) # # TODO this will work for phonons, but not for the other types of perturbations. # ph_inp = q_inp.deepcopy() # rfdir = 3 * [0] # rfdir[pert.idir -1] = 1 # ph_inp.set_vars( # rfdir=rfdir, # rfatpol=[pert.ipert, pert.ipert] # ) # ph_inputs.append(ph_inp) # Split input into gs_inp and ph_inputs all_inps = [gs_inp] all_inps.extend(ph_inputs.split_datasets()) return all_inps
def prepare_for_submission(self, folder): """ Create input files. :param folder: an `aiida.common.folders.Folder` where the plugin should temporarily place all files needed by the calculation. :return: `aiida.common.datastructures.CalcInfo` instance """ ### SETUP ### local_copy_list = [] ### INPUT CHECK ### # PSEUDOS for kind in self.inputs.structure.get_kind_names(): if kind not in self.inputs.pseudos: raise ValueError(f'no pseudo available for element {kind}') elif not isinstance(self.inputs.pseudos[kind], (Psp8Data, JthXmlData)): raise ValueError(f'pseudo for element {kind} is not of type Psp8Data or JthXmlData') # KPOINTS if 'ngkpt' in self.inputs.parameters.keys(): raise ValueError('`ngkpt` should not be specified in input parameters') if 'kptopt' in self.inputs.parameters.keys(): raise ValueError('`kptopt` should not be specified in input parameters') ### PREPARATION ### # PSEUDOS folder.get_subfolder(self._DEFAULT_PSEUDO_SUBFOLDER, create=True) for kind in self.inputs.structure.get_kind_names(): psp = self.inputs.pseudos[kind] local_copy_list.append((psp.uuid, psp.filename, self._DEFAULT_PSEUDO_SUBFOLDER + kind + '.psp8')) # KPOINTS kpoints_mesh = self.inputs.kpoints.get_kpoints_mesh()[0] ### INPUTS ### input_parameters = self.inputs.parameters.get_dict() shiftk = input_parameters.pop('shiftk', [0.0, 0.0, 0.0]) # TODO: There must be a better way to do this # maybe we can convert the PseudoPotential objects into pymatgen Pseudo objects? znucl = structure_to_abivars(self.inputs.structure.get_pymatgen())['znucl'] pseudo_parameters = { 'pseudos': '"' + ', '.join([Element.from_Z(Z).symbol + '.psp8' for Z in znucl]) + '"', 'pp_dirpath': '"' + self._DEFAULT_PSEUDO_SUBFOLDER + '"' } input_parameters = {**input_parameters, **pseudo_parameters} abin = AbinitInput( structure=self.inputs.structure.get_pymatgen(), pseudos=HGH_TABLE, abi_kwargs=input_parameters ) abin.set_kmesh( ngkpt=kpoints_mesh, shiftk=shiftk ) with io.open(folder.get_abs_path(self._DEFAULT_INPUT_FILE), mode='w', encoding='utf-8') as f: f.write(abin.to_string(with_pseudos=False)) ### CODE ### codeinfo = datastructures.CodeInfo() codeinfo.code_uuid = self.inputs.code.uuid codeinfo.cmdline_params = [self.options.input_filename] codeinfo.stdout_name = self.metadata.options.output_filename codeinfo.withmpi = self.inputs.metadata.options.withmpi ### CALC INFO ### calcinfo = datastructures.CalcInfo() calcinfo.codes_info = [codeinfo] calcinfo.stdin_name = self.options.input_filename calcinfo.stdout_name = self.options.output_filename calcinfo.retrieve_list = [self.metadata.options.output_filename] calcinfo.retrieve_list = [self._DEFAULT_OUTPUT_FILE, self._DEFAULT_GSR_FILE_NAME, self._DEFAULT_TRAJECT_FILE_NAME] calcinfo.remote_symlink_list = [] calcinfo.remote_copy_list = [] calcinfo.local_copy_list = local_copy_list if 'parent_calc_folder' in self.inputs: comp_uuid = self.inputs.parent_calc_folder.computer.uuid remote_path = self.inputs.parent_calc_folder.get_remote_path() copy_info = (comp_uuid, remote_path, self._DEFAULT_PARENT_CALC_FLDR_NAME) # If running on the same computer - make a symlink. if self.inputs.code.computer.uuid == comp_uuid: calcinfo.remote_symlink_list.append(copy_info) # If not - copy the folder. else: calcinfo.remote_copy_list.append(copy_info) return calcinfo