예제 #1
0
파일: MCmodel.py 프로젝트: myrusia/Science
 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)
예제 #2
0
 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)
예제 #3
0
 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)
예제 #4
0
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
예제 #5
0
    def test_apply_transformation(self):
        trans = MagOrderingTransformation({"Fe": 5})
        p = Poscar.from_file(os.path.join(test_dir, 'POSCAR.LiFePO4'),
                             check_for_POTCAR=False)
        s = p.structure
        alls = trans.apply_transformation(s, 10)
        self.assertEqual(len(alls), 3)
        f = SpacegroupAnalyzer(alls[0]["structure"], 0.1)
        self.assertEqual(f.get_space_group_number(), 31)

        model = IsingModel(5, 5)
        trans = MagOrderingTransformation({"Fe": 5},
                                          energy_model=model)
        alls2 = trans.apply_transformation(s, 10)
        # Ising model with +J penalizes similar neighbor magmom.
        self.assertNotEqual(alls[0]["structure"], alls2[0]["structure"])
        self.assertEqual(alls[0]["structure"], alls2[2]["structure"])

        s = self.get_structure('Li2O')
        # Li2O doesn't have magnetism of course, but this is to test the
        # enumeration.
        trans = MagOrderingTransformation({"Li+": 1}, max_cell_size=3)
        alls = trans.apply_transformation(s, 100)
        # TODO: check this is correct, unclear what len(alls) should be
        self.assertEqual(len(alls), 12)

        trans = MagOrderingTransformation({"Ni": 5})
        alls = trans.apply_transformation(self.NiO.get_primitive_structure(),
                                          return_ranked_list=10)

        self.assertArrayAlmostEqual(self.NiO_AFM_111.lattice.parameters,
                                    alls[0]["structure"].lattice.parameters)
        self.assertArrayAlmostEqual(self.NiO_AFM_001.lattice.parameters,
                                    alls[1]["structure"].lattice.parameters)
예제 #6
0
    def test_apply_transformation(self):
        trans = MagOrderingTransformation({"Fe": 5})
        p = Poscar.from_file(os.path.join(test_dir, 'POSCAR.LiFePO4'),
                             check_for_POTCAR=False)
        s = p.structure
        alls = trans.apply_transformation(s, 10)
        self.assertEqual(len(alls), 3)
        f = SpacegroupAnalyzer(alls[0]["structure"], 0.1)
        self.assertEqual(f.get_spacegroup_number(), 31)

        model = IsingModel(5, 5)
        trans = MagOrderingTransformation({"Fe": 5}, energy_model=model)
        alls2 = trans.apply_transformation(s, 10)
        #Ising model with +J penalizes similar neighbor magmom.
        self.assertNotEqual(alls[0]["structure"], alls2[0]["structure"])
        self.assertEqual(alls[0]["structure"], alls2[2]["structure"])

        s = self.get_structure('Li2O')
        #Li2O doesn't have magnetism of course, but this is to test the
        # enumeration.
        trans = MagOrderingTransformation({"Li+": 1}, max_cell_size=3)
        alls = trans.apply_transformation(s, 100)
        self.assertEqual(len(alls), 10)
예제 #7
0
 def test_to_from_dict(self):
     m = IsingModel(5, 4)
     d = m.as_dict()
     o = IsingModel.from_dict(d)
     self.assertIsInstance(o, IsingModel)
     self.assertAlmostEqual(o.j, 5)
예제 #8
0
 def test_to_from_dict(self):
     m = IsingModel(5, 4)
     d = m.as_dict()
     o = IsingModel.from_dict(d)
     self.assertIsInstance(o, IsingModel)
     self.assertAlmostEqual(o.j, 5)
예제 #9
0
                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))
예제 #10
0
파일: MCmodel.py 프로젝트: myrusia/Science
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