def Find_Lowest_Energy_Structure_Electrostatics(self): """ Find oxidized/reduced combination with lowest electrostatic energy """ n_Na = self.structure.composition['Na'] n_S = self.structure.composition['S'] n_O = self.structure.composition['O'] n_N = self.structure.composition['N'] n_Fe = self.structure.composition['Fe'] n_Fe_reduced = self.variable_magnetization_dict['Fe']['n_reduced'] n_Fe_oxidized = n_Fe-n_Fe_reduced N_charge = ( 2.*n_O-6.*n_S-n_Na-3.*n_Fe_oxidized-2.*n_Fe_reduced )/n_N oxidation_states = {'Na':+1, 'Fe':+3, 'O':-2,'S':+6,'N':N_charge} Fe_2plus = pymatgen.Specie('Fe',oxidation_state=+2) structure_with_charges = self.structure.copy() structure_with_charges.add_oxidation_state_by_element(oxidation_states) # identify Fe sites list_Fe_indices = [] for i,site in enumerate(structure_with_charges): if site.specie.symbol == 'Fe': list_Fe_indices.append(i) # Generate all possible permutation of sites and compute # Ewald energy ewald_model = EwaldElectrostaticModel(acc_factor=6) list_reduced_sets = [] list_ewald_energy = [] for reduced_set in itertools.combinations(list_Fe_indices,n_Fe_reduced): list_reduced_sets.append(reduced_set) struct = structure_with_charges.copy() for i in reduced_set: struct.replace(i, Fe_2plus) list_ewald_energy.append(ewald_model.get_energy(struct)) if len(list_ewald_energy) == 0: # all sites are oxidized. No sorting involved list_reduced_site_indices = [] list_oxidized_site_indices = list_Fe_indices else: # some reduction takes place. Identify best electrostatic choice imin = np.argmin(list_ewald_energy) list_reduced_site_indices = list_reduced_sets[imin] list_oxidized_site_indices = [] for i in list_Fe_indices: if i not in list_reduced_site_indices: list_oxidized_site_indices.append(i) return list_reduced_site_indices, list_oxidized_site_indices
import pymatgen as mg si = mg.Element("Si") print("Atomic mass of Si is {}".format(si.atomic_mass)) print("Si has a melting point of {}".format(si.melting_point)) print("Ionic radii for Si: {}".format(si.ionic_radii)) print("Atomic mass of Si in kg: {}".format(si.atomic_mass.to("kg"))) fe2 = mg.Specie("Fe", 2) print(fe2.atomic_mass) print(fe2.ionic_radius) comp = mg.Composition("Fe2O3") print("Weight of Fe2O3 is {}".format(comp.weight)) print("Amount of Fe in Fe2O3 is {}".format(comp["Fe"])) print("Atomic fraction of Fe is {}".format(comp.get_atomic_fraction("Fe"))) print("Weight fraction of Fe is {}".format(comp.get_wt_fraction("Fe"))) # Creates cubic Lattice with lattice parameter 4.2 lattice = mg.Lattice.cubic(4.2) print(lattice.lengths_and_angles) structure = mg.Structure(lattice, ["Cs", "Cl"], [[0, 0, 0], [0.5, 0.5, 0.5]]) print("Unit cell vol = {}".format(structure.volume)) print("First site of the structure is {}".format(structure[0])) structure.make_supercell([2, 2, 1]) #Make a 3 x 2 x 1 supercell of the structure del structure[0] #Remove the first site structure.append("Na", [0, 0, 0]) #Append a Na atom.
def _modify_structure(self): # We'll use "oxidation_state" as a stand-in for "magnetisation" # surrounded by nitrogen self.Fe_HS_2plus = pymatgen.Specie('Fe',oxidation_state=4) self.Fe_HS_3plus = pymatgen.Specie('Fe',oxidation_state=5) # surrounded by carbon self.Fe_LS_2plus = pymatgen.Specie('Fe',oxidation_state=0) self.Fe_LS_3plus = pymatgen.Specie('Fe',oxidation_state=1) Fe = pymatgen.Element('Fe') Na = pymatgen.Element('Na') N = pymatgen.Element('N') C = pymatgen.Element('C') Na_indices = self.structure.indices_from_symbol('Na') neibhor_distance = 2.6 # angstrom # Interrogate the structure: for each Fe, what is the site index, the nearest neighbor # and the distance to Na? # create a nice verbose object for this job Iron_Ion = namedtuple('Iron_Ion',['structure_index', 'neighbor', 'distance_to_Na']) # Count the number of reducing electrons which must be introduced number_of_reducing_electrons = self.structure.composition['Na'] list_Fe_ions = [] # Identify all the Fe ions in the structure for i,site in enumerate(self.structure.sites): if site.specie == Fe: neighbor = self.structure.get_neighbors(site,neibhor_distance)[0][0].specie if number_of_reducing_electrons > 0: distance = np.min(self.structure.distance_matrix[i,Na_indices]) else: distance = np.infty list_Fe_ions.append( Iron_Ion(i,neighbor,distance) ) # Spoof pymatgen by substituting reduced iron for the plain vanilla Fe. while number_of_reducing_electrons > 0: next_ion = self.find_next_site_to_reduce_pop(list_Fe_ions) if next_ion.neighbor == N: self.structure.replace(next_ion.structure_index,self.Fe_HS_2plus ) elif next_ion.neighbor == C: self.structure.replace(next_ion.structure_index,self.Fe_LS_2plus ) number_of_reducing_electrons -= 1 # Spoof pymatgen by substituting oxidized iron for the plain vanilla Fe for the remaining sites for next_ion in list_Fe_ions: if next_ion.neighbor == N: self.structure.replace(next_ion.structure_index,self.Fe_HS_3plus ) elif next_ion.neighbor == C: self.structure.replace(next_ion.structure_index,self.Fe_LS_3plus ) # Sort structure, so that decorated sites are # next to each other self.structure.sort() self.structure_has_been_modified = True return