def get_capped_cluster(atoms, folder_path, file_name, save_traj, EF_O_index): """ #TODO: check whether capping is necessary Inconsistent capping (remove all caps for now, does not need this cluster to be physical) Possible fix: change mult in neighbor list Extract smaller cluster containing the extra-framework atoms and cap all the O. Then the capped cluster is moved to the center of the cell to avoid boundary issue. Save cluster in both .traj file and .pdb format. :param atoms: :param folder_path: :param file_name: :param save_traj: if True, save clusters into .traj as well, for later comparison and trouble shooting :param EF_O_index: if not none, will use this value, else, will find the index using Extraframework code :return: 1. EF-cluster including 13 atoms, index of the EF atoms in original zeolite, index of the EF atoms in the current cluster (the later two output index lists share the ordering) """ EFMaker = ExtraFrameworkAnalyzer(atoms) cluster = atoms[[ index for index in EFMaker.get_extraframework_cluster(EF_O_index) ]] cluster_EF_index = get_EF_atom_indices(cluster) centering_pos = cluster.get_positions()[cluster_EF_index[-1]] recentered_cluster = EFMaker.recentering_atoms(cluster, centering_pos)[0] # FIXME: recentering doesn't work well for very small unit cells. eg. SOD # cluster = Zeolite(cluster).cap_atoms() proteindatabank.write_proteindatabank(folder_path + '/%s.pdb' % file_name, recentered_cluster) if save_traj is True: write(folder_path + '/%s.traj' % file_name, recentered_cluster) return cluster, EFMaker.get_extraframework_cluster( EF_O_index), cluster_EF_index
def optimize_geometry(self, atoms, params, coeff=0.005, cutoff_lim=0.1, cutoff=100): # eventually need three atoms, along three force directions, move with constant steps # now, moving the entire extra framework along the direction count = 1 while abs(cutoff) >= cutoff_lim: EF_analyzer = ExtraFrameworkAnalyzer(atoms) EF_analyzer.get_extraframework() EF_indices = EF_analyzer.EF_indices cutoff = EF_analyzer.get_predicted_forces(params) dir = self.get_opt_dir(params, EF_analyzer.EF_bond_vectors) original_pos = atoms.get_positions()[EF_indices] del atoms[EF_indices] atoms = atoms + Atoms('CuOCu', positions=original_pos + coeff * dir) print(abs(cutoff)) count += 1 if count == 300: break print('number of iterations =', count)
def get_EF_O_index(traj): """ get the mode of EF_O, and use that to extract the EF cluster for the force field training all EF atoms should have the same indices regardless of there is binds on the zeolite, as long as the zeolite framework is the same - (all EF atoms, aka. Cu-O-Cu insertion follows the same procedures) :param traj: traj of configurations containing all atoms, including both the zeolite backbone and EF atoms """ EF_O_index_list = [] for atoms in traj: try: EFAnalyzer = ExtraFrameworkAnalyzer(atoms) EF_O_index_list.append(EFAnalyzer.get_extraframework_cluster()[-1]) except: ... return mode(tuple(EF_O_index_list))
def get_good_initial_traj(traj, tag, round_num, f_lim): good_traj = [] x_list = [] y_list = [] z_list = [] for atoms in traj: EF_analyzer = ExtraFrameworkAnalyzer(atoms) EF_analyzer.get_extraframework() val = [f[0] for f in EF_analyzer.get_forces().values()] if tag == 'Cu': val = val[0] if tag == 'O': val = val[2] if np.round(val[0], round_num) not in x_list and np.round(val[1], round_num) not in y_list and \ np.round(val[2], round_num) not in z_list and abs(val[0]) < f_lim \ and abs(val[1]) < f_lim and abs(val[2]) < f_lim: x_list.append(np.round(val[0], round_num)) y_list.append(np.round(val[1], round_num)) z_list.append(np.round(val[2], round_num)) good_traj.append(atoms) return good_traj
def get_properties(self): for atoms in self.traj: EF_analyzer = ExtraFrameworkAnalyzer(atoms) EF_analyzer.get_extraframework() self.bond.append(EF_analyzer.EF_bond_vectors) self.angle.append(EF_analyzer.EF_angles) self.angle_dir.append(EF_analyzer.get_angle_force_dir()) self.ref_forces.append(EF_analyzer.get_forces()) self.good_atoms.append(atoms) # self.bad_atoms.append(atoms) # todo: function handles bad atoms if self.scalar is True: self.ref_f_scalar = self.get_all_ref_forces()[1] else: self.ref_f_scalar = self.get_all_ref_forces()[0]