def test_lammps(otf_object, structure): atom_types = [1, 2] atom_masses = [108, 127] atom_species = [1, 2] * 27 # create data file lammps_location = 'AgI_Molten_15.txt' data_file_name = 'tmp.data' data_text = lammps_calculator.lammps_dat(structure, atom_types, atom_masses, atom_species) lammps_calculator.write_text(data_file_name, data_text) # create lammps input style_string = 'mgpf' # use mgpf for the new lammps executable pair_style, # because mgp is the energy version coeff_string = '* * {} Ag I yes yes'.format(lammps_location) lammps_executable = '$lmp' dump_file_name = 'tmp.dump' input_file_name = 'tmp.in' output_file_name = 'tmp.out' input_text = \ lammps_calculator.generic_lammps_input(data_file_name, style_string, coeff_string, dump_file_name) lammps_calculator.write_text(input_file_name, input_text) lammps_calculator.run_lammps(lammps_executable, input_file_name, output_file_name) lammps_forces = lammps_calculator.lammps_parser(dump_file_name) # check that lammps agrees with gp to within 1 meV/A forces = otf_object.force_list[-1] assert(np.abs(lammps_forces[0, 1] - forces[0, 1]) < 1e-3) os.system('rm tmp.in tmp.out tmp.dump tmp.data' ' log.lammps') os.system('rm '+lammps_location) os.system('rm grid3*.npy') os.system('rm -r kv3')
atom_types = [1, 2] atom_masses = [108, 127] atom_species = [1, 2] * 27 # create data file data_file_name = 'tmp.data' data_text = lammps_calculator.lammps_dat(structure, atom_types, atom_masses, atom_species) lammps_calculator.write_text(data_file_name, data_text) # create lammps input style_string = 'mgp' coeff_string = '* * {} Ag I yes yes'.format(lammps_location) lammps_executable = '$lmp' dump_file_name = 'tmp.dump' input_file_name = 'tmp.in' output_file_name = 'tmp.out' input_text = \ lammps_calculator.generic_lammps_input(data_file_name, style_string, coeff_string, dump_file_name) lammps_calculator.write_text(input_file_name, input_text) lammps_calculator.run_lammps(lammps_executable, input_file_name, output_file_name) lammps_forces = lammps_calculator.lammps_parser(dump_file_name) # check that lammps agrees with gp to within 1 meV/A assert (np.abs(lammps_forces[0, 1] - forces[0, 1]) < 1e-3)
def test_lmp_predict(all_gp, all_mgp, bodies, multihyps): """ test the lammps implementation """ for f in os.listdir("./"): if f in [ f'tmp{bodies}{multihyps}in', f'tmp{bodies}{multihyps}out', f'tmp{bodies}{multihyps}dump', f'tmp{bodies}{multihyps}data', 'log.lammps' ]: os.remove(f) clean() mgp_model = all_mgp[f'{bodies}{multihyps}'] gp_model = all_gp[f'{bodies}{multihyps}'] lammps_location = mgp_model.lmp_file_name # lmp file is automatically written now every time MGP is constructed mgp_model.write_lmp_file(lammps_location) # create test structure cell = np.eye(3) nenv = 10 unique_species = gp_model.training_data[0].species cutoffs = gp_model.cutoffs struc_test, f = get_random_structure(cell, unique_species, nenv) atom_num = 1 test_envi = env.AtomicEnvironment(struc_test, atom_num, cutoffs) atom_types = [1, 2] atom_masses = [108, 127] atom_species = struc_test.coded_species # create data file data_file_name = f'tmp{bodies}{multihyps}.data' data_text = lammps_calculator.lammps_dat(struc_test, atom_types, atom_masses, atom_species) lammps_calculator.write_text(data_file_name, data_text) # create lammps input by = 'no' ty = 'no' if '2' in bodies: by = 'yes' if '3' in bodies: ty = 'yes' style_string = 'mgp' coeff_string = f'* * {lammps_location} H He {by} {ty}' lammps_executable = os.environ.get('lmp') dump_file_name = f'tmp{bodies}{multihyps}.dump' input_file_name = f'tmp{bodies}{multihyps}.in' output_file_name = f'tmp{bodies}{multihyps}.out' input_text = \ lammps_calculator.generic_lammps_input(data_file_name, style_string, coeff_string, dump_file_name, newton=True) lammps_calculator.write_text(input_file_name, input_text) lammps_calculator.run_lammps(lammps_executable, input_file_name, output_file_name) lammps_forces = lammps_calculator.lammps_parser(dump_file_name) mgp_forces = mgp_model.predict(test_envi, mean_only=True) # check that lammps agrees with gp to within 1 meV/A for i in range(3): assert (np.abs(lammps_forces[atom_num, i] - mgp_forces[0][i]) < 1e-3) for f in os.listdir("./"): if f in [ f'tmp{bodies}{multihyps}in', f'tmp{bodies}{multihyps}out', f'tmp{bodies}{multihyps}dump', f'tmp{bodies}{multihyps}data', 'log.lammps', lammps_location ]: os.remove(f) clean()
def test_parse_header(): # ------------------------------------------------------------------------- # reconstruct gp model from otf snippet # ------------------------------------------------------------------------- file_name = 'test_files/AgI_snippet.out' hyp_no = 2 # parse otf output otf_object = otf_parser.OtfAnalysis(file_name) otf_cell = otf_object.header['cell'] # reconstruct gp model kernel = mc_simple.two_plus_three_body_mc kernel_grad = mc_simple.two_plus_three_body_mc_grad gp_model = otf_object.make_gp(kernel=kernel, kernel_grad=kernel_grad, hyp_no=hyp_no) gp_model.par = True gp_model.hyp_labels = ['sig2', 'ls2', 'sig3', 'ls3', 'noise'] # ------------------------------------------------------------------------- # check gp reconstruction # ------------------------------------------------------------------------- # create test structure species = np.array([47, 53] * 27) positions = otf_object.position_list[-1] forces = otf_object.force_list[-1] structure = struc.Structure(otf_cell, species, positions) atom = 0 environ = env.AtomicEnvironment(structure, atom, gp_model.cutoffs) force_comp = 2 pred, _ = gp_model.predict(environ, force_comp) assert (np.isclose(pred, forces[0][1])) # ------------------------------------------------------------------------- # map the potential # ------------------------------------------------------------------------- file_name = 'AgI.gp' grid_num_2 = 64 grid_num_3 = 15 lower_cut = 2. two_cut = 7. three_cut = 5. lammps_location = 'AgI_Molten_15.txt' # set struc params. cell and masses arbitrary? mapped_cell = np.eye(3) * 100 struc_params = { 'species': [47, 53], 'cube_lat': mapped_cell, 'mass_dict': { '0': 27, '1': 16 } } # grid parameters grid_params = { 'bounds_2': [[lower_cut], [two_cut]], 'bounds_3': [[lower_cut, lower_cut, 0], [three_cut, three_cut, np.pi]], 'grid_num_2': grid_num_2, 'grid_num_3': [grid_num_3, grid_num_3, grid_num_3], 'svd_rank_2': 64, 'svd_rank_3': 90, 'bodies': [2, 3], 'load_grid': None, 'update': True } mgp_model = MappedGaussianProcess(gp_model, grid_params, struc_params, mean_only=True, lmp_file_name=lammps_location) # ------------------------------------------------------------------------- # test the mapped potential # ------------------------------------------------------------------------- gp_pred_x = gp_model.predict(environ, 1) mgp_pred = mgp_model.predict(environ, mean_only=True) # check mgp is within 1 meV/A of the gp assert (np.abs(mgp_pred[0][0] - gp_pred_x[0]) < 1e-3) # ------------------------------------------------------------------------- # check lammps potential # ------------------------------------------------------------------------- # mgp_model.write_lmp_file(lammps_location) # lmp file is automatically written now every time MGP is constructed # create test structure species = otf_object.gp_species_list[-1] positions = otf_object.position_list[-1] forces = otf_object.force_list[-1] structure = struc.Structure(otf_cell, species, positions) atom_types = [1, 2] atom_masses = [108, 127] atom_species = [1, 2] * 27 # create data file data_file_name = 'tmp.data' data_text = lammps_calculator.lammps_dat(structure, atom_types, atom_masses, atom_species) lammps_calculator.write_text(data_file_name, data_text) # create lammps input style_string = 'mgp' #TODO: change the name of lammps coeff_string = '* * {} 47 53 yes yes'.format(lammps_location) lammps_executable = '$lmp' dump_file_name = 'tmp.dump' input_file_name = 'tmp.in' output_file_name = 'tmp.out' input_text = \ lammps_calculator.generic_lammps_input(data_file_name, style_string, coeff_string, dump_file_name) lammps_calculator.write_text(input_file_name, input_text) lammps_calculator.run_lammps(lammps_executable, input_file_name, output_file_name) lammps_forces = lammps_calculator.lammps_parser(dump_file_name) # check that lammps agrees with gp to within 1 meV/A assert (np.abs(lammps_forces[0, 1] - forces[0, 1]) < 1e-3) os.system('rm tmp.in tmp.out tmp.dump tmp.data AgI_Molten_15.txt' ' log.lammps') os.system('rm grid3*.npy') os.system('rm -r kv3')
def test_lammps(): sgp_py.write_mapping_coefficients("beta.txt", "A", 0) new_kern = sgp_py.write_varmap_coefficients("beta_var.txt", "B", 0) # here the new kernel needs to be returned, otherwise the kernel won't be found in the current module assert sgp_py.sparse_gp.sparse_indices[0] == sgp_py.sgp_var.sparse_indices[0], \ "the sparse_gp and sgp_var don't have the same training data" for s in range(len(atom_types)): org_desc = sgp_py.sparse_gp.sparse_descriptors[0].descriptors[s] new_desc = sgp_py.sgp_var.sparse_descriptors[0].descriptors[s] if not np.allclose(org_desc, new_desc): # the atomic order might change assert np.allclose(org_desc.shape, new_desc.shape) for i in range(org_desc.shape[0]): flag = False for j in range(new_desc.shape[0]): # seek in new_desc for matching of org_desc if np.allclose(org_desc[i], new_desc[j]): flag = True break assert flag, "the sparse_gp and sgp_var don't have the same descriptors" # set up input and data files data_file_name = "tmp.data" lammps_location = "beta.txt" style_string = "flare" coeff_string = "* * {}".format(lammps_location) lammps_executable = os.environ.get("lmp") dump_file_name = "tmp.dump" input_file_name = "tmp.in" output_file_name = "tmp.out" newton = True # write data file data_text = lammps_calculator.lammps_dat( test_structure, atom_types, atom_masses, species ) lammps_calculator.write_text(data_file_name, data_text) # write input file input_text = lammps_calculator.generic_lammps_input( data_file_name, style_string, coeff_string, dump_file_name, newton=newton, std_string="beta_var.txt", std_style="flare_pp", ) lammps_calculator.write_text(input_file_name, input_text) # run lammps lammps_calculator.run_lammps(lammps_executable, input_file_name, output_file_name) # read output lmp_dump = read(dump_file_name, format="lammps-dump-text") lmp_forces = lmp_dump.get_forces() # lmp_var_1 = lmp_dump.get_array("c_std[1]") # lmp_var_2 = lmp_dump.get_array("c_std[2]") # lmp_var_3 = lmp_dump.get_array("c_std[3]") # lmp_var = np.hstack([lmp_var_1, lmp_var_2, lmp_var_3]) lmp_std = lmp_dump.get_array("c_std") lmp_var = lmp_std ** 2 print(lmp_var) # compare with sgp_py prediction assert len(sgp_py.training_data) > 0 # Convert coded species to 0, 1, 2, etc. coded_species = [] for spec in test_structure.coded_species: coded_species.append(species_map[spec]) test_cpp_struc = Structure( test_structure.cell, coded_species, test_structure.positions, sgp_py.cutoff, sgp_py.descriptor_calculators, ) print("GP predicting") sgp_py.sparse_gp.predict_DTC(test_cpp_struc) sgp_efs = test_cpp_struc.mean_efs sgp_forces = np.reshape(sgp_efs[1:len(sgp_efs)-6], (test_structure.nat, 3)) assert np.allclose(lmp_forces, sgp_forces) print("GP forces match LMP forces") sgp_py.sgp_var.predict_DTC(test_cpp_struc) #sgp_var = np.reshape(test_cpp_struc_pow1.variance_efs[1:len(sgp_efs)-6], (test_structure.nat, 3)) sgp_var = sgp_py.sgp_var.compute_cluster_uncertainties(test_cpp_struc) # sgp_var = test_cpp_struc.variance_efs[0] print(sgp_var) n_descriptors = np.shape(test_cpp_struc.descriptors[0].descriptors[0])[1] n_species = len(atom_types) desc_en = np.zeros((n_species, n_descriptors)) py_var = 0.0 # for s in range(n_species): # n_struc_s = test_cpp_struc_pow1.descriptors[0].n_clusters_by_type[s]; # assert np.shape(test_cpp_struc_pow1.descriptors[0].descriptors[s])[0] == n_struc_s # for i in range(n_descriptors): # desc_en[s, i] = np.sum(test_cpp_struc_pow1.descriptors[0].descriptors[s][:, i] / test_cpp_struc_pow1.descriptors[0].descriptor_norms[s], axis=0) # print("len(varmap_coeffs)", len(sgp_py.sgp_var.varmap_coeffs)) beta_matrices = [] for s1 in range(n_species): # for s2 in range(n_species): beta_matr = np.reshape(sgp_py.sgp_var.varmap_coeffs[s1, :], (n_descriptors, n_descriptors)) print(s1, s1, "max", np.max(np.abs(beta_matr)), beta_matr.shape) beta_matrices.append(beta_matr) # py_var += desc_en[s1, :].dot(desc_en[s1, :].dot(beta_matr)) # print(py_var) struc_desc = test_cpp_struc.descriptors[0] n_descriptors = np.shape(struc_desc.descriptors[0])[1] n_species = len(atom_types) # desc = np.zeros((n_atoms, 3, n_species, n_descriptors)) print("len(varmap_coeffs)", len(sgp_py.sgp_var.varmap_coeffs)) py_var = np.zeros(n_atoms) for s in range(n_species): n_struc = struc_desc.n_clusters_by_type[s]; beta_matr = beta_matrices[s] for j in range(n_struc): norm = struc_desc.descriptor_norms[s][j] n_neigh = struc_desc.neighbor_counts[s][j] c_neigh = struc_desc.cumulative_neighbor_counts[s][j] atom_index = struc_desc.atom_indices[s][j] print("atom", atom_index, "n_neigh", n_neigh) desc = struc_desc.descriptors[s][j] py_var[atom_index] = desc.dot(desc.dot(beta_matr)) / norm ** 2 #py_var[atom_index] = desc.dot(desc) / norm ** 2 * sgp_py.sgp_var.kernels[0].sigma ** 2 # for k in range(n_neigh): # ind = c_neigh + k # neighbor_index = struc_desc.neighbor_indices[s][ind]; # # neighbor_coord = struc_desc.neighbor_coordinates[s][ind]; # neigh_dist = np.sum((neighbor_coord - test_positions[atom_index]) ** 2) # #print("neighbor", neighbor_index, "dist", neigh_dist) # for comp in range(3): # f1 = struc_desc.descriptor_force_dervs[s][3 * ind + comp] / norm # f2 = struc_desc.descriptors[s][j] * struc_desc.descriptor_force_dots[s][3 * ind + comp] / norm ** 3 # f3 = f1 - f2 # desc[atom_index, comp, s, :] += norm #f3 # desc[neighbor_index, comp, s, :] -= norm #f3 # # # for i in range(n_atoms): # for comp in range(3): # for s1 in range(n_species): # for s2 in range(n_species): # beta_matr = np.reshape(sgp_py.sgp_var.varmap_coeffs[s1 * n_species + s2, :], (n_descriptors, n_descriptors)) ## print(s1, s2, "max", np.max(np.abs(beta_matr))) # py_var[i, comp] += desc[i, comp, s1].dot(desc[i, comp, s2].dot(beta_matr)) ## py_var[i, comp] += np.sum(desc[i, comp, s1]) #np.sum(beta_matr[:, comp]) #np.sum(desc[i, comp, s1]) print(py_var)
def test_lmp_predict(all_gp, all_mgp, bodies, multihyps): """ test the lammps implementation """ pytest.skip() prefix = f'{bodies}{multihyps}' mgp_model = all_mgp[f'{bodies}{multihyps}'] gp_model = all_gp[f'{bodies}{multihyps}'] lammps_location = mgp_model.lmp_file_name # create test structure cell = 5 * np.eye(3) nenv = 10 unique_species = gp_model.training_data[0].species cutoffs = gp_model.cutoffs struc_test, f = get_random_structure(cell, unique_species, nenv) atom_num = 1 test_envi = env.AtomicEnvironment(struc_test, atom_num, cutoffs, cutoffs_mask=gp_model.hyps_mask) all_species = list(set(struc_test.coded_species)) atom_types = list(np.arange(len(all_species)) + 1) atom_masses = [_Z_to_mass[spec] for spec in all_species] atom_species = [ all_species.index(spec) + 1 for spec in struc_test.coded_species ] specie_symbol_list = " ".join( [_Z_to_element[spec] for spec in all_species]) # create data file data_file_name = f'{prefix}.data' data_text = lammps_calculator.lammps_dat(struc_test, atom_types, atom_masses, atom_species) lammps_calculator.write_text(data_file_name, data_text) # create lammps input by = 'no' ty = 'no' if '2' in bodies: by = 'yes' if '3' in bodies: ty = 'yes' style_string = 'mgp' coeff_string = f'* * {lammps_location}.mgp {specie_symbol_list} {by} {ty}' std_string = f'{lammps_location}.var {specie_symbol_list} {by} {ty}' lammps_executable = os.environ.get('lmp') dump_file_name = f'{prefix}.dump' input_file_name = f'{prefix}.in' output_file_name = f'{prefix}.out' input_text = \ lammps_calculator.generic_lammps_input(data_file_name, style_string, coeff_string, dump_file_name, newton=False, std_string=std_string) lammps_calculator.write_text(input_file_name, input_text) lammps_calculator.run_lammps(lammps_executable, input_file_name, output_file_name) pred_std = True lammps_forces, lammps_stds = lammps_calculator.lammps_parser( dump_file_name, std=pred_std) mgp_pred = mgp_model.predict(test_envi) # check that lammps agrees with gp to within 1 meV/A for i in range(3): print("isclose? diff:", lammps_forces[atom_num, i] - mgp_pred[0][i], "mgp value", mgp_pred[0][i]) assert np.isclose(lammps_forces[atom_num, i], mgp_pred[0][i], rtol=1e-2) # check the lmp var mgp_std = np.sqrt(mgp_pred[1]) print("isclose? diff:", lammps_stds[atom_num] - mgp_std, "mgp value", mgp_std) assert np.isclose(lammps_stds[atom_num], mgp_std, rtol=1e-2) clean(prefix=prefix)