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()
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()
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")
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()