def test_alpha_sio2(self): """Testing wyckoff positions for alpha-SiO2""" asi02 = Structure.from_file( os.path.join(abidata.dirpath, "refs", "mp-7000_DDB.bz2")) ss = asi02.site_symmetries df = ss.get_wyckoff_dataframe(verbose=2) df = df[df["element"] == "Si"] self.assert_equal(df["xfrac"].values, ["xfrac", "yfrac", "0.0"]) self.assert_equal(df["yfrac"].values, ["0.0", "yfrac", "yfrac"]) self.assert_equal(np.array(df["zfrac"].values, dtype=float), [0.833335, 0.5, 0.166665]) """ wyckoff site_symmetry Txx Tyy Tzz Txy Txz Tyz 0 3a 2 (#3,nsym:2) Txx Tyy Tzz Tyy/2 Tyz/2 Tyz 1 3a 2 (#3,nsym:2) Tyy Tyy Tzz Txy -Tyz Tyz 2 3a 2 (#3,nsym:2) 2*Txy Tyy Tzz Txy 2*Tyz Tyz """ df = ss.get_tensor_rank2_dataframe(verbose=2) ref = ["Txx", "Tyy", "2*Txy"] self.assert_equal(df["Txx"].values, ref) ref = ["Tyy", "Tyy", "Tyy"] self.assert_equal(df["Tyy"].values, ref) ref = ["Tzz", "Tzz", "Tzz"] self.assert_equal(df["Tzz"].values, ref) ref = ["Tyy/2", "Txy", "Txy"] self.assert_equal(df["Txy"].values, ref) ref = ["Tyz/2", "-Tyz", "2*Tyz"] self.assert_equal(df["Txz"].values, ref) ref = ["Tyz", "Tyz", "Tyz"] self.assert_equal(df["Tyz"].values, ref)
def read_structure(self): """ Overrides the ``read_structure`` method so that we always return an instance of AbiPy |Structure| object """ from abipy.core.structure import Structure return Structure.from_file(self.path)
def abifile_subclass_from_filename(filename): from abipy.iotools.files import AbinitFile, AbinitLogFile, AbinitOutputFile from abipy.electrons import SIGRES_File, GSR_File, MDF_File from abipy.waves import WFK_File #from abipy.phonons import PHDOS_File, PHBST_File ext2ncfile = { "SIGRES.nc": SIGRES_File, "WFK-etsf.nc": WFK_File, "MDF.nc" : MDF_File, "GSR.nc": GSR_File #"PHDOS.nc": PHDOS_File, #"PHBST.nc": PHBST_File, } #if filename.endswith(".abi"): # return AbinitInputFile if filename.endswith(".abo"): return AbinitOutputFile if filename.endswith(".log"): return AbinitLogFile # CIF files. if filename.endswith(".cif"): from abipy.core.structure import Structure return Structure.from_file(filename) ext = filename.split("_")[-1] try: return ext2ncfile[ext] except KeyError: raise KeyError("No class has been registered for extension %s" % ext)
def work_for_pseudo(self, pseudo, accuracy="normal", kppa=6750, ecut=None, pawecutdg=None, toldfe=1.e-9, smearing="fermi_dirac:0.1 eV", workdir=None, manager=None, **kwargs): """ Returns a :class:`Work` object from the given pseudopotential. Args: kwargs: Extra variables passed to Abinit. .. note:: 0.001 Rydberg is the value used with WIEN2K """ pseudo = Pseudo.as_pseudo(pseudo) symbol = pseudo.symbol if pseudo.ispaw and pawecutdg is None: raise ValueError("pawecutdg must be specified for PAW calculations.") try: cif_path = self.get_cif_path(symbol) except Exception as exc: raise self.Error(str(exc)) # Include spin polarization for O, Cr and Mn (antiferromagnetic) # and Fe, Co, and Ni (ferromagnetic). # antiferromagnetic Cr, O # ferrimagnetic Mn spin_mode = "unpolarized" if symbol in ["Fe", "Co", "Ni"]: spin_mode = "polarized" if symbol == "Fe": kwargs['spinat'] = 2 * [(0, 0, 2.3)] if symbol == "Co": kwargs['spinat'] = 2 * [(0, 0, 1.2)] if symbol == "Ni": kwargs['spinat'] = 4 * [(0, 0, 0.6)] if symbol in ["O", "Cr", "Mn"]: spin_mode = "afm" if symbol == 'O': kwargs['spinat'] = [(0, 0, 1.5), (0, 0, 1.5), (0, 0, -1.5), (0, 0, -1.5)] elif symbol == 'Cr': kwargs['spinat'] = [(0, 0, 1.5), (0, 0, -1.5)] elif symbol == 'Mn': kwargs['spinat'] = [(0, 0, 2.0), (0, 0, 1.9), (0, 0, -2.0), (0, 0, -1.9)] # DO NOT CHANGE THE STRUCTURE REPORTED IN THE CIF FILE. structure = Structure.from_file(cif_path, primitive=False) # Magnetic elements: # Start from previous SCF run to avoid getting trapped in local minima connect = symbol in ("Fe", "Co", "Ni", "Cr", "Mn", "O", "Zn", "Cu") return DeltaFactorWork( structure, pseudo, kppa, connect, spin_mode=spin_mode, toldfe=toldfe, smearing=smearing, accuracy=accuracy, ecut=ecut, pawecutdg=pawecutdg, ecutsm=0.5, workdir=workdir, manager=manager, **kwargs)
def work_for_pseudo(self, pseudo, kppa=3000, maxene=250, ecut=None, pawecutdg=None, spin_mode="unpolarized", include_soc=False, tolwfr=1.e-12, smearing="fermi_dirac:0.1 eV", workdir=None, manager=None, **kwargs): """ Returns a :class:`Work` object from the given pseudopotential. Args: pseudo: :class:`Pseudo` object. kppa: Number of k-points per reciprocal atom. ecut: Cutoff energy in Hartree pawecutdg: Cutoff energy of the fine grid (PAW only) spin_mode: Spin polarization option tolwfr: Tolerance on the residuals. smearing: Smearing technique. workdir: Working directory. manager: :class:`TaskManager` object. kwargs: Extra variables passed to Abinit. """ if pseudo.ispaw and pawecutdg is None: raise ValueError( "pawecutdg must be specified for PAW calculations.") if pseudo.xc != self._dfdb.xc: raise ValueError( "Pseudo xc differs from the XC used to instantiate the factory\n" "Pseudo: %s, Database: %s" % (pseudo.xc, self._dfdb.xc)) try: cif_path = self.get_cif_path(pseudo.symbol) except Exception as exc: raise self.Error(str(exc)) # DO NOT CHANGE THE STRUCTURE REPORTED IN THE CIF FILE. structure = Structure.from_file(cif_path, primitive=False) return GhostsWork(structure, pseudo, kppa, maxene, spin_mode=spin_mode, include_soc=include_soc, tolwfr=tolwfr, smearing=smearing, ecut=ecut, pawecutdg=pawecutdg, ecutsm=0.5, workdir=workdir, manager=manager, **kwargs)
def work_for_pseudo(self, pseudo, kppa=6750, ecut=None, pawecutdg=None, toldfe=1.e-9, smearing="fermi_dirac:0.1 eV", include_soc=False, workdir=None, manager=None, **kwargs): """ Returns a :class:`Work` object from the given pseudopotential. Args: pseudo: :class:`Pseudo` object. kppa: kpoint per reciprocal atom ecut: Cutoff energy in Hartree pawecutdg: Cutoff energy of the fine grid (PAW only) toldfe: Tolerance on the energy (Ha) smearing: Smearing technique. include_soc: True if pseudo has SO contributions and calculation should be done with nspinor=2 workdir: String specifing the working directory. manager: :class:`TaskManager` responsible for the submission of the tasks. kwargs: Extra variables passed to Abinit. .. note:: 0.001 Rydberg is the value used with WIEN2K """ symbol = pseudo.symbol if pseudo.ispaw and pawecutdg is None: raise ValueError("pawecutdg must be specified for PAW calculations.") if pseudo.xc != self._dfdb.xc: raise ValueError( "Pseudo xc differs from the XC used to instantiate the factory\n" "Pseudo: %s, Database: %s" % (pseudo.xc, self._dfdb.xc)) try: cif_path = self.get_cif_path(symbol) except Exception as exc: raise self.Error(str(exc)) # WARNING: DO NOT CHANGE THE STRUCTURE REPORTED IN THE CIF FILE. structure = Structure.from_file(cif_path, primitive=False) # Include spin polarization and initial spinat for particular elements # TODO: Not sure spinat is ok if LDA. kwargs["spinat"], spin_mode = self._dfdb.spinat_spinmode_for_symbol(symbol) if include_soc: spin_mode = "spinor" # This is needed for LDA if symbol in ("O", "Mn"): print("Got Oxygen or Mn") spin_mode = "polarized" # Magnetic elements: # Start from previous SCF run to avoid getting trapped in local minima connect = symbol in ("Fe", "Co", "Ni", "Cr", "Mn", "O", "Zn", "Cu") return DeltaFactorWork( structure, pseudo, kppa, connect, spin_mode=spin_mode, include_soc=include_soc, toldfe=toldfe, smearing=smearing, ecut=ecut, pawecutdg=pawecutdg, ecutsm=0.5, workdir=workdir, manager=manager, **kwargs)
def work_for_pseudo(self, pseudo, **kwargs): """ Create a :class:`Flow` for phonon calculations: 1) One workflow for the GS run. 2) nqpt workflows for phonon calculations. Each workflow contains nirred tasks where nirred is the number of irreducible phonon perturbations for that particular q-point. the kwargs are passed to scf_hp_inputs """ try: qpt = kwargs['qpt'] except IndexError: raise ValueError('A phonon test needs to specify a qpoint.') kwargs.pop('accuracy') pseudo = Pseudo.as_pseudo(pseudo) structure_or_cif = self.get_cif_path(pseudo.symbol) if not isinstance(structure_or_cif, Structure): # Assume CIF file structure = Structure.from_file(structure_or_cif, primitive=False) else: structure = structure_or_cif nat = len(structure) report = pseudo.read_dojo_report() ecut_str = '%.1f' % kwargs['ecut'] #print(ecut_str) #print(report['deltafactor'][float(ecut_str)].keys()) try: v0 = nat * report['deltafactor'][ecut_str]['v0'] except KeyError: try: v0 = nat * report['deltafactor'][float(ecut_str)]['v0'] except KeyError: # the df calculation at this ecut is not done already so the phonon task can not be created return None structure.scale_lattice(v0) all_inps = self.scf_ph_inputs(pseudos=[pseudo], structure=structure, **kwargs) scf_input, ph_inputs = all_inps[0], all_inps[1:] work = build_oneshot_phononwork(scf_input=scf_input, ph_inputs=ph_inputs, work_class=PhononDojoWork) #print('after build_oneshot_phonon') #print(work) work.set_dojo_trial(qpt) #print(scf_input.keys()) work.ecut = scf_input['ecut'] work._pseudo = pseudo return work
def test_si(self): """Testing wyckoff positions for Si2""" si = Structure.from_file(abidata.cif_file("si.cif")) ss = si.site_symmetries repr(ss) str(ss) assert ss.to_string(verbose=2) df = ss.get_wyckoff_dataframe(verbose=2) self.assert_equal(np.array(df["xfrac"].values, dtype=float), [0, 0.25]) self.assert_equal(np.array(df["yfrac"].values, dtype=float), [0, 0.25]) self.assert_equal(np.array(df["zfrac"].values, dtype=float), [0, 0.25]) #0 -43m (#31) nsym:24 0 0 0 #1 -43m (#31) nsym:24 0.250000000000000 0.250000000000000 0.250000000000000 df = ss.get_tensor_rank2_dataframe(verbose=2) ref = ["Tzz", "Tzz"] self.assert_equal(df["Txx"].values, ref) self.assert_equal(df["Tyy"].values, ref) ref = ["-Tzz/3", "-Tzz/3"] self.assert_equal(df["Txy"].values, ref) self.assert_equal(df["Txz"].values, ref) self.assert_equal(df["Tyz"].values, ref)
def work_for_pseudo(self, pseudo, kppa=3000, maxene=250, ecut=None, pawecutdg=None, spin_mode="unpolarized", include_soc=False, tolwfr=1.e-12, smearing="fermi_dirac:0.1 eV", workdir=None, manager=None, **kwargs): """ Returns a :class:`Work` object from the given pseudopotential. Args: pseudo: :class:`Pseudo` object. kppa: Number of k-points per reciprocal atom. ecut: Cutoff energy in Hartree pawecutdg: Cutoff energy of the fine grid (PAW only) spin_mode: Spin polarization option tolwfr: Tolerance on the residuals. smearing: Smearing technique. workdir: Working directory. manager: :class:`TaskManager` object. kwargs: Extra variables passed to Abinit. """ if pseudo.ispaw and pawecutdg is None: raise ValueError("pawecutdg must be specified for PAW calculations.") if pseudo.xc != self._dfdb.xc: raise ValueError( "Pseudo xc differs from the XC used to instantiate the factory\n" "Pseudo: %s, Database: %s" % (pseudo.xc, self._dfdb.xc)) try: cif_path = self.get_cif_path(pseudo.symbol) except Exception as exc: raise self.Error(str(exc)) # DO NOT CHANGE THE STRUCTURE REPORTED IN THE CIF FILE. structure = Structure.from_file(cif_path, primitive=False) return GhostsWork( structure, pseudo, kppa, maxene, spin_mode=spin_mode, include_soc=include_soc, tolwfr=tolwfr, smearing=smearing, ecut=ecut, pawecutdg=pawecutdg, ecutsm=0.5, workdir=workdir, manager=manager, **kwargs)
def read_structure(self): from abipy.core.structure import Structure return Structure.from_file(self.path)
def structure_from_cif(filename): """ Returnn an Abipy structure from the basename of the cif file in data/cifs. """ return Structure.from_file(cif_file(filename))
def work_for_pseudo(self, pseudo, kppa=1000, ecut=None, pawecutdg=None, smearing="fermi_dirac:0.1 eV", include_soc=False, workdir=None, manager=None): """ Create and return a :class:`RelaxAndAddPhGammaWork` object. Args: pseudo: filepath or :class:`Pseudo` object. kppa: Number of k-points per reciprocal atom. ecut: Cutoff energy in Hartree pawecutdg: Cutoff energy of the fine grid (PAW only) smearing: Smearing technique. include_soc=True of SOC should be included. workdir: Working directory. manager: :class:`TaskManager` object. """ symbol = pseudo.symbol if pseudo.ispaw and pawecutdg is None: raise ValueError("pawecutdg must be specified for PAW calculations.") if pseudo.xc != self._dfdb.xc: raise ValueError( "Pseudo xc differs from the XC used to instantiate the factory\n" "Pseudo: %s, Database: %s" % (pseudo.xc, self._dfdb.xc)) qpt = np.zeros(3) self.include_soc = include_soc try: cif_path = self.get_cif_path(pseudo.symbol) except Exception as exc: raise self.Error(str(exc)) # DO NOT CHANGE THE STRUCTURE REPORTED IN THE CIF FILE. structure = Structure.from_file(cif_path, primitive=False) # Get spinat and spin_mode from df database. spinat, spin_mode = self._dfdb.spinat_spinmode_for_symbol(symbol) # DFPT with AFM is not supported. Could try AFM in Relax and then polarized # in WFK + DFPT but this one is safer. if spin_mode == "afm": spin_mode = "polarized" if include_soc: spin_mode = "spinor" # Build inputs for structural relaxation. multi = ion_ioncell_relax_input( structure, pseudo, kppa=kppa, nband=None, ecut=ecut, pawecutdg=pawecutdg, accuracy="normal", spin_mode=spin_mode, smearing=smearing) # Set spinat from internal database. multi.set_vars(chkprim=0, mem_test=0, spinat=spinat) # Construct a *specialized" work for structural relaxation # This work will create a new workflow for phonon calculations # with the final relaxed structure (see on_all_ok below). work = RelaxAndAddPhGammaWork(ion_input=multi[0], ioncell_input=multi[1]) # Monkey patch work work.dojo_kppa = kppa work.dojo_qpt = qpt work.ecut = ecut work.dojo_pawecutdg = pawecutdg work.dojo_include_soc = include_soc work._dojo_trial = "phgamma" if not include_soc else "phgamma_soc" work.dojo_pseudo = pseudo return work