Example #1
0
def test_struc_from_ase():
    from ase import Atoms
    from ase.calculators.singlepoint import SinglePointCalculator

    results = {
        "forces": np.random.randn(20, 3),
        "energy": np.random.rand(),
        "stress": np.random.randn(6),
    }

    uc = Atoms(
        ["Pd" for i in range(10)] + ["Ag" for i in range(10)],
        positions=np.random.rand(20, 3),
        cell=np.random.rand(3, 3),
    )

    calculator = SinglePointCalculator(uc, **results)
    uc.set_calculator(calculator)

    new_struc = Structure.from_ase_atoms(uc)

    assert np.all(new_struc.species_labels == uc.get_chemical_symbols())
    assert np.all(new_struc.positions == uc.get_positions())
    assert np.all(new_struc.cell == uc.get_cell())
    assert np.all(new_struc.forces == results["forces"])
    assert np.all(new_struc.energy == results["energy"])
    assert np.all(new_struc.stress == results["stress"])
Example #2
0
    def restart(self):
        # Recover atomic configuration: positions, velocities, forces
        positions, self.nsteps = self.read_frame('positions.xyz', -1)
        self.atoms.set_positions(positions)
        self.atoms.set_velocities(self.read_frame('velocities.dat', -1)[0])
        self.atoms.calc.results['forces'] = self.read_frame('forces.dat',
                                                            -1)[0]
        print('Last frame recovered')

        # Recover training data set
        gp_model = self.atoms.calc.gp_model
        atoms = deepcopy(self.atoms)
        nat = len(self.atoms.positions)
        dft_positions = self.read_all_frames('dft_positions.xyz', nat)
        dft_forces = self.read_all_frames('dft_forces.dat', nat)
        added_atoms = self.read_all_frames('added_atoms.dat', 1, 1, 'int')
        for i, frame in enumerate(dft_positions):
            atoms.set_positions(frame)
            curr_struc = Structure.from_ase_atoms(atoms)
            gp_model.update_db(curr_struc, dft_forces[i], added_atoms[i])
        gp_model.set_L_alpha()
        print('GP training set ready')

        # Recover FLARE calculator
        gp_model.ky_mat_inv = np.load(self.restart_from + '/ky_mat_inv.npy')
        gp_model.alpha = np.load(self.restart_from + '/alpha.npy')
        if self.atoms.calc.use_mapping:
            for map_3 in self.atoms.calc.mgp_model.maps_3:
                map_3.load_grid = self.restart_from + '/'
            self.atoms.calc.build_mgp(skip=False)
        print('GP and MGP ready')

        self.l_bound = 10
Example #3
0
    def otf_run(self, steps):
        """Perform a number of time steps."""
        # initialize gp by a dft calculation
        if not self.atoms.calc.gp_model.training_data:
            self.dft_count = 0
            self.std_in_bound = False
            self.target_atom = 0
            self.stds = []
            dft_forces = self.call_DFT()
            f = dft_forces

            # update gp model
            atom_struc = Structure(np.array(self.atoms.cell),
                                   self.atoms.get_atomic_numbers(),
                                   self.atoms.positions)
            self.atoms.calc.gp_model.update_db(atom_struc,
                                               dft_forces,
                                               custom_range=self.init_atoms)

            # train calculator
            self.train()
            print('mgp model:', self.atoms.calc.mgp_model)

        if self.md_engine == 'NPT':
            if not self.initialized:
                self.initialize()
            else:
                if self.have_the_atoms_been_changed():
                    raise NotImplementedError(
                        "You have modified the atoms since the last timestep.")

        for i in range(steps):
            print('step:', i)
            if self.md_engine == 'NPT':
                self.step()
            else:
                f = self.step(f)
            self.nsteps += 1
            self.stds = self.atoms.get_uncertainties()

            # figure out if std above the threshold
            self.call_observers()
            curr_struc = Structure.from_ase_atoms(self.atoms)
            curr_struc.stds = self.stds
            noise = self.atoms.calc.gp_model.hyps[-1]
            self.std_in_bound, self.target_atoms = is_std_in_bound(\
                    noise, self.std_tolerance, curr_struc, self.max_atoms_added)

            #self.is_std_in_bound([])

            if not self.std_in_bound:
                # call dft/eam
                print('calling dft')
                dft_forces = self.call_DFT()

                # update gp
                print('updating gp')
                self.update_GP(dft_forces)

        self.observers[0][0].run_complete()
Example #4
0
def test_struc_from_ase():
    from ase import Atoms
    uc = Atoms(['Pd' for i in range(10)] + ['Ag' for i in range(10)],
               positions=np.random.rand(20, 3),
               cell=np.random.rand(3, 3))
    new_struc = Structure.from_ase_atoms(uc)
    assert np.all(new_struc.species_labels == uc.get_chemical_symbols())
    assert np.all(new_struc.positions == uc.get_positions())
    assert np.all(new_struc.cell == uc.get_cell())
Example #5
0
    def update_GP(self, dft_forces):
        atom_count = 0
        atom_list = []
        gp_model = self.atoms.calc.gp_model

        # build gp structure from atoms
        atom_struc = Structure.from_ase_atoms(self.atoms)

        while (not self.std_in_bound and atom_count < np.min(
            [self.max_atoms_added,
             len(self.target_atoms)])):

            target_atom = self.target_atoms[atom_count]

            # update gp model
            gp_model.update_db(atom_struc,
                               dft_forces,
                               custom_range=[target_atom])

            if gp_model.alpha is None:
                gp_model.set_L_alpha()
            else:
                gp_model.update_L_alpha()

            # atom_list.append(target_atom)
            ## force calculation needed before get_uncertainties
            # forces = self.atoms.calc.get_forces_gp(self.atoms)
            # self.stds = self.atoms.get_uncertainties()

            # write added atom to the log file,
            # refer to ase.optimize.optimize.Dynamics
            self.observers[0][0].add_atom_info(target_atom,
                                               self.stds[target_atom])

            #self.is_std_in_bound(atom_list)
            atom_count += 1

        self.train()
        self.observers[0][0].added_atoms_dat.write('\n')
        self.observers[0][0].write_wall_time()
Example #6
0
    def otf_run(self, steps, rescale_temp=[], rescale_steps=[]):
        """
        Use `otf_run` intead of `run` to perform a number of time steps.

        Args:
            steps (int): the number of time steps

        Other Parameters:
            rescale_temp (list): a list of temepratures that rescale the system
            rescale_steps (list): a list of step numbers that the temperature
                rescaling in `rescale_temp` is done

        Example:
            # rescale temperature to 500K and 1000K at the 100th and 200th step
            rescale_temp = [500, 1000]
            rescale_steps = [100, 200]
        """

        # restart from previous OTF training
        if self.restart_from is not None:
            self.restart()
            f = self.atoms.calc.results['forces']

        # initialize gp by a dft calculation
        if not self.atoms.calc.gp_model.training_data:
            self.dft_count = 0
            self.stds = np.zeros((self.noa, 3))
            dft_forces = self.call_DFT()
            f = dft_forces

            # update gp model
            curr_struc = Structure.from_ase_atoms(self.atoms)
            self.l_bound = get_l_bound(100, curr_struc, self.two_d)
            print('l_bound:', self.l_bound)

            self.atoms.calc.gp_model.update_db(curr_struc,
                                               dft_forces,
                                               custom_range=self.init_atoms)

            # train calculator
            for atom in self.init_atoms:
                # the observers[0][0] is the logger
                self.observers[0][0].add_atom_info(atom, self.stds[atom])
            self.train()
            self.observers[0][0].write_wall_time()

        if self.md_engine == 'NPT':
            if not self.initialized:
                self.initialize()
            else:
                if self.have_the_atoms_been_changed():
                    raise NotImplementedError(
                        "You have modified the atoms since the last timestep.")

        step_0 = self.nsteps
        for i in range(step_0, steps):
            print('step:', i)
            self.atoms.calc.results = {
            }  # clear the calculation from last step
            self.stds = np.zeros((self.noa, 3))

            # temperature rescaling
            if self.nsteps in rescale_steps:
                temp = rescale_temp[rescale_steps.index(self.nsteps)]
                curr_velocities = self.atoms.get_velocities()
                curr_temp = self.atoms.get_temperature()
                self.atoms.set_velocities(curr_velocities *\
                                          np.sqrt(temp/curr_temp))

            if self.md_engine == 'NPT':
                self.step()
            else:
                f = self.step(f)
            self.nsteps += 1
            self.stds = self.atoms.get_uncertainties(self.atoms)

            # figure out if std above the threshold
            self.call_observers()
            curr_struc = Structure.from_ase_atoms(self.atoms)
            self.l_bound = get_l_bound(self.l_bound, curr_struc, self.two_d)
            print('l_bound:', self.l_bound)
            curr_struc.stds = np.copy(self.stds)
            noise = self.atoms.calc.gp_model.hyps[-1]
            self.std_in_bound, self.target_atoms = is_std_in_bound(\
                    noise, self.std_tolerance, curr_struc, self.max_atoms_added)

            print('std in bound:', self.std_in_bound, self.target_atoms)
            #self.is_std_in_bound([])

            if not self.std_in_bound:
                # call dft/eam
                print('calling dft')
                dft_forces = self.call_DFT()

                # update gp
                print('updating gp')
                self.update_GP(dft_forces)

        self.observers[0][0].run_complete()