Exemple #1
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()
Exemple #2
0
    def run(self):
        self.output.write_header(self.gp.cutoffs, self.gp.kernel_name,
                                 self.gp.hyps, self.gp.algo, self.dt,
                                 self.number_of_steps, self.structure,
                                 self.std_tolerance)
        counter = 0
        self.start_time = time.time()

        while self.curr_step < self.number_of_steps:
            print('curr_step:', self.curr_step)
            # run DFT and train initial model if first step and DFT is on
            if self.curr_step == 0 and self.std_tolerance != 0:
                # call dft and update positions
                self.run_dft()
                dft_frcs = copy.deepcopy(self.structure.forces)
                new_pos = md.update_positions(self.dt, self.noa,
                                              self.structure)
                self.update_temperature(new_pos)
                self.record_state()

                # make initial gp model and predict forces
                self.update_gp(self.init_atoms, dft_frcs)
                if (self.dft_count - 1) < self.freeze_hyps:
                    self.train_gp()

            # after step 1, try predicting with GP model
            else:
                self.gp.check_L_alpha()
                self.pred_func(self.structure, self.gp, self.no_cpus)
                self.dft_step = False
                new_pos = md.update_positions(self.dt, self.noa,
                                              self.structure)

                # get max uncertainty atoms
                std_in_bound, target_atoms = is_std_in_bound(
                    self.std_tolerance, self.gp.hyps[-1], self.structure,
                    self.max_atoms_added)

                if not std_in_bound:
                    # record GP forces
                    self.update_temperature(new_pos)
                    self.record_state()
                    gp_frcs = copy.deepcopy(self.structure.forces)

                    # run DFT and record forces
                    self.dft_step = True
                    self.run_dft()
                    dft_frcs = copy.deepcopy(self.structure.forces)
                    new_pos = md.update_positions(self.dt, self.noa,
                                                  self.structure)
                    self.update_temperature(new_pos)
                    self.record_state()

                    # compute mae and write to output
                    mae = np.mean(np.abs(gp_frcs - dft_frcs))
                    mac = np.mean(np.abs(dft_frcs))

                    self.output.write_to_log('\nmean absolute error:'
                                             ' %.4f eV/A \n' % mae)
                    self.output.write_to_log('mean absolute dft component:'
                                             ' %.4f eV/A \n' % mac)

                    # add max uncertainty atoms to training set
                    self.update_gp(target_atoms, dft_frcs)
                    if (self.dft_count - 1) < self.freeze_hyps:
                        self.train_gp()

            # write gp forces
            if counter >= self.skip and not self.dft_step:
                self.update_temperature(new_pos)
                self.record_state()
                counter = 0

            counter += 1
            self.update_positions(new_pos)
            self.curr_step += 1

        self.output.conclude_run()
Exemple #3
0
    def run(self):
        """
        Performs an on-the-fly training run.

        If OTF has store_dft_output set, then the specified DFT files will
        be copied with the current date and time prepended in the format
        'Year.Month.Day:Hour:Minute:Second:'.
        """

        self.output.write_header(self.gp.cutoffs, self.gp.kernel_name,
                                 self.gp.hyps, self.gp.opt_algorithm, self.dt,
                                 self.number_of_steps, self.structure,
                                 self.std_tolerance)
        counter = 0
        self.start_time = time.time()

        while self.curr_step < self.number_of_steps:
            # run DFT and train initial model if first step and DFT is on
            if self.curr_step == 0 and self.std_tolerance != 0 and len(
                    self.gp.training_data) == 0:
                # call dft and update positions
                self.run_dft()
                dft_frcs = copy.deepcopy(self.structure.forces)
                new_pos = md.update_positions(self.dt, self.noa,
                                              self.structure)
                self.update_temperature(new_pos)
                self.record_state()

                # make initial gp model and predict forces
                self.update_gp(self.init_atoms, dft_frcs)
                if (self.dft_count - 1) < self.freeze_hyps:
                    self.train_gp()
                    if self.write_model >= 2:
                        self.gp.write_model(self.output_name + "_model")

            # after step 1, try predicting with GP model
            else:
                self.gp.check_L_alpha()
                self.pred_func(self.structure, self.gp, self.n_cpus)
                self.dft_step = False
                new_pos = md.update_positions(self.dt, self.noa,
                                              self.structure)

                # get max uncertainty atoms
                std_in_bound, target_atoms = \
                    is_std_in_bound(self.std_tolerance,
                                    self.gp.hyps[-1], self.structure,
                                    self.max_atoms_added)

                if not std_in_bound:
                    # record GP forces
                    self.update_temperature(new_pos)
                    self.record_state()
                    gp_frcs = copy.deepcopy(self.structure.forces)

                    # run DFT and record forces
                    self.dft_step = True
                    self.run_dft()
                    dft_frcs = copy.deepcopy(self.structure.forces)
                    new_pos = md.update_positions(self.dt, self.noa,
                                                  self.structure)
                    self.update_temperature(new_pos)
                    self.record_state()

                    # compute mae and write to output
                    mae = np.mean(np.abs(gp_frcs - dft_frcs))
                    mac = np.mean(np.abs(dft_frcs))

                    self.output.write_to_log('\nmean absolute error:'
                                             ' %.4f eV/A \n' % mae)
                    self.output.write_to_log('mean absolute dft component:'
                                             ' %.4f eV/A \n' % mac)

                    # add max uncertainty atoms to training set
                    self.update_gp(target_atoms, dft_frcs)

                    if (self.dft_count - 1) < self.freeze_hyps:
                        self.train_gp()
                        if self.write_model == 2:
                            self.gp.write_model(self.output_name + "_model")
                    if self.write_model == 3:
                        self.gp.write_model(self.output_name + '_model')

            # write gp forces
            if counter >= self.skip and not self.dft_step:
                self.update_temperature(new_pos)
                self.record_state()
                counter = 0

            counter += 1
            self.update_positions(new_pos)
            self.curr_step += 1

        self.output.conclude_run()

        if self.write_model >= 1:
            self.gp.write_model(self.output_name + "_model")
Exemple #4
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()