def get_madelung_tag_single(rundict, force=False, verbose=0, oxi_int=False): struct_data = rundict.structure_data if not force and struct_data[0].properties.get("E_mad", None) is not None: print("skipping") return True poscar, potcar = [p.from_file(rundict.job_folder+f) for (p, f) in [(Poscar, "/POSCAR"), (Potcar, "/POTCAR")]] s_dict = {} if verbose > 0: print("poscar/potcar parsed") if oxi_int: oxi = rundict.structure.copy() try: oxi.add_oxidation_state_by_guess() except ValueError: print("Forced to set oxidation by hand") oxi.add_oxidation_state_by_element({"Na": 1, "Mg": 2, "Mn": 3.5, "O": -2, "Li": 1, "Ca": 2, "Fe": 3, "Zn": 4, "Co": 2.5, "Ti": 4, "S": -2, 'P': 5}) ew_sum_int = EwaldSummation(oxi) oxi.add_site_property("E_mad_int", [ew_sum_int.get_site_energy(i) for i in range(oxi.num_sites)]) s_dict['oxi_int'] = oxi struct_data.add_site_property("E_mad_int", [ew_sum_int.get_site_energy(i) for i in range(oxi.num_sites)]) if verbose > 0: print("integer oxidation state computed") if struct_data[0].properties.get("charge", None) is None: print("No bader charges => no bader madelung") return False # Test if bader charges were computed correctly get_oxidation_state_decorated_structure(struct_data, potcar, poscar) if verbose > 0: print("bader oxidation state computed") ew_sum = EwaldSummation(rundict.structure_data) # madelung_array = [] struct_data.add_site_property("E_mad", [ew_sum.get_site_energy(i) for i in range(struct_data.num_sites)]) s_dict["oxi_bader"] = struct_data print(" ".join(s_dict.values())) return True
def test_site(self): """Test that uses an uncharged structure""" filepath = os.path.join(test_dir, "POSCAR") p = Poscar.from_file(filepath, check_for_POTCAR=False) original_s = p.structure s = original_s.copy() s.add_oxidation_state_by_element({"Li": 1, "Fe": 3, "P": 5, "O": -2}) # Comparison to LAMMPS result ham = EwaldSummation(s, compute_forces=True) self.assertAlmostEquals(-1226.3335, ham.total_energy, 3) self.assertAlmostEquals(-45.8338, ham.get_site_energy(0), 3) self.assertAlmostEquals(-27.2978, ham.get_site_energy(8), 3)
def test_site(self): """Test that uses an uncharged structure""" filepath = os.path.join(test_dir, 'POSCAR') p = Poscar.from_file(filepath, check_for_POTCAR=False) original_s = p.structure s = original_s.copy() s.add_oxidation_state_by_element({"Li": 1, "Fe": 3, "P": 5, "O": -2}) # Comparison to LAMMPS result ham = EwaldSummation(s, compute_forces=True) self.assertAlmostEquals(-1226.3335, ham.total_energy, 3) self.assertAlmostEquals(-45.8338, ham.get_site_energy(0), 3) self.assertAlmostEquals(-27.2978, ham.get_site_energy(8), 3)
def calc_elem_max_potential(structure_oxid: mg.Structure, full_list=False, check_vesta=False): """ Return the maximum Madelung potential for all elements in a structure. :param structure_oxid: Pymatgen Structure with oxidation states for each site :param full_list: Boolean, if True, return all the site potentials associated with the element :param check_vesta: Boolean, if True, convert all site potentials' units from V to e/Angstrom :return: Dictionary: {Pymatgen Element: maximum Madelung potential for that element} or {Pymatgen Element: list of all Madelung potentials for that element} """ # set the conversion factor if the potential values needs to be compared with the ones from VESTA # conversion value obtained from page 107 of https://jp-minerals.org/vesta/archives/VESTA_Manual.pdf if check_vesta: vesta_conversion = 14.39965 else: vesta_conversion = 1 # define a dictionary that stores the oxidation states for all the element elem_charge_lookup = { specie.element: specie.oxi_state for specie in structure_oxid.composition.elements } # if there is only one element, then ewald summation will not work if len(elem_charge_lookup) == 1: return {elem: None for elem in elem_charge_lookup.keys()} # initialize the Ewald Summation object in order to calculate Ewald site energy ews = EwaldSummation(structure_oxid) # obtain the site indices where each element occupies elem_indices, *_ = get_elem_info(structure_oxid, makesupercell=False) # get the site potential using indices # the Ewald site energy is converted to site potential using V=2E/q # TODO: need to resolve division by zero error message site_potentials = { elem: [ 2 * ews.get_site_energy(index) / (elem_charge_lookup[elem] * vesta_conversion) for index in indices ] for elem, indices in elem_indices.items() } if full_list: return site_potentials return { elem: max(potentials) for elem, potentials in site_potentials.items() }
def featurize(self, strc, idx): """ Args: struct (Structure): Pymatgen Structure object. idx (int): index of target site in structure. Returns: ([float]) - Electrostatic energy of the site """ # Check if the new input is the last # Note: We use 'is' rather than structure comparisons for speed if strc is self.__last_structure: ewald = self.__last_ewald else: self.__last_structure = strc ewald = EwaldSummation(strc, acc_factor=self.accuracy) self.__last_ewald = ewald return [ewald.get_site_energy(idx)]
def get_I_mads(struc): # Add oxidation states try: struc = bva.get_oxi_state_decorated_structure(struc) #print (struc) except: struc.add_oxidation_state_by_guess() # Check if a specific species is present if (Specie('I',-1) in struc.species): ews = EwaldSummation(struc) print (ews) I_indices = [n for n,site in enumerate(struc) if site.specie.symbol == 'I'] I_mads = np.array([ews.get_site_energy(n) for n in I_indices]) print (I_indices) print (I_mads) return I_mads return ews.total_energy print (ews.total_energy)
def featurize(self, strc, idx): """ Args: struct (Structure): Pymatgen Structure object. idx (int): index of target site in structure. Returns: ([float]) - Electrostatic energy of the site """ # Check if the new input is the last # Note: We use 'is' rather than structure comparisons for speed # # TODO: Figure out if this implementation is thread-safe! I was debating adding # Locks, but think we are OK if strc is self.__last_structure: ewald = self.__last_ewald else: self.__last_structure = strc ewald = EwaldSummation(strc, acc_factor=self.accuracy) self.__last_ewald = ewald return [ewald.get_site_energy(idx)]