def test_get_energy(self): m = IsingModel(5, 6) from pymatgen.core.periodic_table import Specie s = Structure.from_file(os.path.join(test_dir, "LiFePO4.cif")) s.replace_species({"Fe": Specie("Fe", 2, {"spin": 4})}) self.assertAlmostEqual(m.get_energy(s), 172.81260515787977) s[4] = Specie("Fe", 2, {"spin": -4}) s[5] = Specie("Fe", 2, {"spin": -4}) self.assertAlmostEqual(m.get_energy(s), 51.97424405382921)
def objective_function_Ising(x, structures): """ :param x: list of E0 and J :param structures: vasp calculated structures :return: error = (property_predicted - property_target) ** 2 / delta_tolerance """ model = IsingModel(x[1], config['cutoff_radius']) error = sum([(model.get_energy(st) + x[0] - st.vasp_energy)**2 for st in structures]) / config['delta_tolerance'] return error
idx = int(np.where(np.isclose(self.distances, dist))[0]) energy -= self.j[idx] * s1 * getattr(site.specie, "spin", 0) return energy #atoms = read_vasp('POSCAR2') #write_vasp('POSCAR', sort(atoms), vasp5=True, direct=True, label=atoms.get_chemical_formula()) if __name__ == '__main__': """ J = [0.00240319, 0.00224361, 0.00146472, 0.00125072, 0.00122649] model_uuu = MultiIsingModel(J, 5.0, Structure.from_file('2FEPOSCAR'), [3, 3]) model_uuu.recommended_j() model_uud = MultiIsingModel(J, 5.0, Structure.from_file('2FEPOSCAR'), [3, -3]) uuu = model_uuu.get_energy() uud = model_uud.get_energy() print(uuu - uud) """ J = -0.03489 uu = Structure.from_file('2FEPOSCAR') ud = uu.copy() uu.add_spin_by_site([3.291, 3.291]) ud.add_spin_by_site([3.285, -3.285]) model = IsingModel(J, 5.0) print(model.get_energy(uu) - model.get_energy(ud)) uuu = Structure.from_file('POSCAR3') uud = uu.copy() uuu.add_spin_by_site([3, 3, 3]) uud.add_spin_by_site([3, 3, -3]) model = IsingModel(J, 5.0) print(model.get_energy(uuu) - model.get_energy(uud))
class MCModel: def __init__(self, config): self.config = config self.mode = self.config['mode'] self.savefile = self.config['savefile'] if self.mode == 'calculate': self.structure = self.make_simulation_grid(self.config['dim']) self.temperature = self.config[ 'temperature'] * 8.6173303e-05 # Boltzmann constant in eV/K self.init_weight = np.array([ x for x in self.config['initial_spin_weight'] ]) / sum(self.config['initial_spin_weight']) self.spins = None self.initialize_spins() self.history = [self.structure.copy()] self.size = len(self.structure) self.model = IsingModel(j=self.config['J'], max_radius=self.config['max_radius']) self.step = 0 self.maxsteps = self.config['maxsteps'] self.energy = self.model.get_energy(self.structure) self.get_magnetization() self.start_time = None self.saveevery = self.config['saveevery'] self.force_stop = False elif self.mode == 'plot': with open(self.savefile, 'rb') as f: self.history = pickle.load(f) def make_simulation_grid(self, dim): atoms = bulk("Fe") structure = AseAtomsAdaptor().get_structure(atoms) structure.make_supercell(dim) return structure def initialize_spins(self): self.spins = np.random.choice( [self.config['spin'], -self.config['spin']], len(self.structure), p=self.init_weight) self.structure.add_spin_by_site(self.spins) def make_step(self): self.step += 1 test_step = deepcopy(self.structure.copy()) idx = np.random.randint(self.size) self.spins[idx] *= -1 test_step.add_spin_by_site(self.spins) energy_after_step = self.model.get_energy(test_step) change = energy_after_step - self.energy p = np.random.rand() print(np.exp((-1.0 * change) / self.temperature), p) if change < 0: self.structure = deepcopy(test_step.copy()) self.energy = energy_after_step self.structure.add_spin_by_site(self.spins) elif np.exp((-1.0 * change) / self.temperature) > p: self.structure = deepcopy(test_step.copy()) self.energy = energy_after_step self.structure.add_spin_by_site(self.spins) else: self.spins[idx] *= -1 self.history.append(self.structure.copy()) self.get_magnetization() if self.step % self.saveevery == 0: with open(self.savefile, 'wb') as f: pickle.dump(self.history, f) if os.path.exists('stop'): self.force_stop = True def get_magnetization(self): m = sum([ getattr(self.structure[idx].specie, "spin") for idx in range(self.size) ]) / self.size print( f'Step {self.step:05d}: magnetization {m:.8f} energy {self.energy:0.6f}' ) def run(self): self.start_time = time() while self.step < self.maxsteps: self.make_step() if self.force_stop: break runtime = time() - self.start_time print( f'Run time {runtime:.1f} seconds, {runtime/self.maxsteps:.3f} second per step' ) def plot(self): pass