def ase_calculator(gp_model, mgp_model): """ test the mapping for mc_simple kernel """ cal = FLARE_Calculator(gp_model, mgp_model, par=False, use_mapping=True) yield cal del cal
def flare_calc(): flare_calc_dict = {} for md_engine in md_list: # ---------- create gaussian process model ------------------- # set up GP hyperparameters kernels = ["twobody", "threebody"] # use 2+3 body kernel parameters = {"cutoff_twobody": 5.0, "cutoff_threebody": 3.5} pm = ParameterHelper(kernels=kernels, random=True, parameters=parameters) hm = pm.as_dict() hyps = hm["hyps"] cut = hm["cutoffs"] print("hyps", hyps) gp_model = GaussianProcess( kernels=kernels, component="sc", # single-component. For multi-comp, use 'mc' hyps=hyps, cutoffs=cut, hyp_labels=["sig2", "ls2", "sig3", "ls3", "noise"], opt_algorithm="L-BFGS-B", n_cpus=1, ) # ----------- create mapped gaussian process ------------------ grid_params = { "twobody": { "grid_num": [64] }, "threebody": { "grid_num": [16, 16, 16] }, } mgp_model = MappedGaussianProcess(grid_params=grid_params, unique_species=[1, 2], n_cpus=1, var_map="pca") # ------------ create ASE's flare calculator ----------------------- flare_calculator = FLARE_Calculator(gp_model, mgp_model=mgp_model, par=True, use_mapping=True) flare_calc_dict[md_engine] = flare_calculator print(md_engine) yield flare_calc_dict del flare_calc_dict
def flare_calc(): flare_calc_dict = {} for md_engine in md_list: # ---------- create gaussian process model ------------------- # set up GP hyperparameters kernels = ['twobody', 'threebody'] # use 2+3 body kernel parameters = {'cutoff_twobody': 5.0, 'cutoff_threebody': 3.5} pm = ParameterHelper(kernels=kernels, random=True, parameters=parameters) hm = pm.as_dict() hyps = hm['hyps'] cut = hm['cutoffs'] print('hyps', hyps) gp_model = GaussianProcess( kernels=kernels, component='sc', # single-component. For multi-comp, use 'mc' hyps=hyps, cutoffs=cut, hyp_labels=['sig2', 'ls2', 'sig3', 'ls3', 'noise'], opt_algorithm='L-BFGS-B', n_cpus=1) # ----------- create mapped gaussian process ------------------ grid_params = { 'twobody': { 'grid_num': [64] }, 'threebody': { 'grid_num': [16, 16, 16] } } mgp_model = MappedGaussianProcess(grid_params=grid_params, unique_species=[1, 2], n_cpus=1, var_map='pca') # ------------ create ASE's flare calculator ----------------------- flare_calculator = FLARE_Calculator(gp_model, mgp_model=mgp_model, par=True, use_mapping=True) flare_calc_dict[md_engine] = flare_calculator print(md_engine) yield flare_calc_dict del flare_calc_dict
def test_otf_parser(md_engine): output_name = f"{md_engine}.out" otf_traj = OtfAnalysis(output_name) try: replicated_gp = otf_traj.make_gp() except: init_flare = FLARE_Calculator.from_file(md_engine + "_flare.json") replicated_gp = otf_traj.make_gp(init_gp=init_flare.gp_model) print("ase otf traj parsed") for f in glob.glob(md_engine + "*"): os.remove(f)
def test_build_map(all_gp, all_mgp, all_ase_calc, bodies, multihyps): """ test the mapping for mc_simple kernel """ # multihyps = False gp_model = all_gp[f'{bodies}{multihyps}'] mgp_model = all_mgp[f'{bodies}{multihyps}'] mgp_model.build_map(gp_model) all_ase_calc[f'{bodies}{multihyps}'] = FLARE_Calculator(gp_model, mgp_model, par=False, use_mapping=True) clean()
def test_otf_parser(md_engine): output_name = f"{md_engine}.out" otf_traj = OtfAnalysis(output_name) try: replicated_gp = otf_traj.make_gp() except: init_flare = FLARE_Calculator.from_file(md_engine + "_flare.json") replicated_gp = otf_traj.make_gp(init_gp=init_flare.gp_model) print("ase otf traj parsed") # Check that the GP forces change. comp1 = otf_traj.force_list[0][1, 0] comp2 = otf_traj.force_list[-1][1, 0] assert (comp1 != comp2) for f in glob.glob(md_engine + "*"): os.remove(f)
def test_otf_parser(md_engine, write_model): output_name = f"{md_engine}_{write_model}" otf_traj = OtfAnalysis(output_name + ".out") try: replicated_gp = otf_traj.make_gp() except: init_flare = FLARE_Calculator.from_file(output_name + "_flare.json") replicated_gp = otf_traj.make_gp(init_gp=init_flare.gp_model) print("ase otf traj parsed") # Check that the GP forces change. comp1 = otf_traj.force_list[-2][1, 0] comp2 = otf_traj.force_list[-1][1, 0] assert comp1 != comp2 for f in glob.glob(output_name + "*"): os.remove(f) for f in glob.glob("*_ckpt_*"): shutil.rmtree(f, ignore_errors=True)
def from_dict(dct): flare_calc_dict = json.load(open(dct["flare_calc"])) # Build FLARE_Calculator from dict if flare_calc_dict["class"] == "FLARE_Calculator": flare_calc = FLARE_Calculator.from_file(dct["flare_calc"]) _kernels = None # Build SGP_Calculator from dict # TODO: we still have the issue that the c++ kernel needs to be # in the current space, otherwise there is Seg Fault # That's why there is the _kernels elif flare_calc_dict["class"] == "SGP_Calculator": from flare_pp.sparse_gp_calculator import SGP_Calculator flare_calc, _kernels = SGP_Calculator.from_file(dct["flare_calc"]) else: raise TypeError( f"The calculator from {dct['flare_calc']} is not recognized." ) flare_calc.reset() dct["atoms"] = read(dct["atoms"]) dct["calculator"] = flare_calc dct.pop("gp") with open(dct["dft_loc"], "rb") as f: dct["dft_calc"] = pickle.load(f) for key in ["dt", "dft_loc"]: dct.pop(key) new_otf = ASE_OTF(**dct) new_otf._kernels = _kernels new_otf.dft_count = dct["dft_count"] new_otf.curr_step = dct["curr_step"] new_otf.std_tolerance = dct["std_tolerance"] if new_otf.md_engine == "NPT": if not new_otf.md.initialized: new_otf.md.initialize() return new_otf
def from_dict(dct): flare_calc = FLARE_Calculator.from_file(dct["flare_calc"]) flare_calc.reset() dct["atoms"] = read(dct["atoms"]) dct["atoms"].calc = flare_calc dct.pop("gp") with open(dct["dft_loc"], "rb") as f: dct["dft_calc"] = pickle.load(f) for key in ["dt", "dft_loc"]: dct.pop(key) new_otf = ASE_OTF(**dct) new_otf.dft_count = dct["dft_count"] new_otf.curr_step = dct["curr_step"] if new_otf.md_engine == "NPT": if not new_otf.md.initialized: new_otf.md.initialize() return new_otf
def from_dict(dct): flare_calc = FLARE_Calculator.from_file(dct["flare_calc"]) # https://github.com/mir-group/flare/commit/88efe67e28f2b6a9cb5c6662675aad0209af134d flare_calc.reset() dct["atoms"] = read(dct["atoms"]) dct["atoms"].calc = flare_calc dct.pop("gp") with open(dct["dft_loc"], "rb") as f: dct["dft_calc"] = pickle.load(f) for key in ["dt", "dft_loc"]: dct.pop(key) new_otf = ASE_OTF(**dct) new_otf.dft_count = dct["dft_count"] new_otf.curr_step = dct["curr_step"] new_otf.std_tolerance = dct["std_tolerance"] if new_otf.md_engine == "NPT": if not new_otf.md.initialized: new_otf.md.initialize() return new_otf
} } # grid parameters lower_cut = 2.5 grid_num_2 = 8 grid_num_3 = 8 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': 0, 'svd_rank_3': 0, 'bodies': [2, 3], 'load_grid': None, 'update': True } mgp_model = MappedGaussianProcess(gp_model.hyps, gp_model.cutoffs, grid_params, struc_params, mean_only=False, container_only=False, GP=gp_model, lmp_file_name='agi.mgp') # ------------ create ASE's flare calculator ----------------------- flare_calc = FLARE_Calculator(gp_model, mgp_model, par=True, use_mapping=True)
def test_stress_with_lammps(): """ Based on gp_test_al.out, ensures that given hyperparameters and DFT calls a GP model can be reproduced and correctly re-predict forces and uncertainties :return: """ # build up GP from a previous trajectory parsed = OtfAnalysis('test_files/VelocityVerlet.log') positions = parsed.position_list forces = parsed.force_list gp_model = parsed.make_gp(kernel=two_plus_three_body_mc, kernel_grad=two_plus_three_body_mc_grad) # build up MGP from GP struc_params = { 'species': [47, 53], 'cube_lat': np.eye(3) * 100, 'mass_dict': { '0': 27, '1': 16 } } # grid parameters lower_cut = 2.5 grid_num_2 = 64 grid_num_3 = 32 two_cut = 5.0 three_cut = 5.0 grid_params = { 'bounds_2': [[lower_cut], [two_cut]], 'bounds_3': [[lower_cut, lower_cut, -1], [three_cut, three_cut, 1]], 'grid_num_2': grid_num_2, 'grid_num_3': [grid_num_3, grid_num_3, grid_num_3], 'svd_rank_2': 0, 'svd_rank_3': 0, 'bodies': [2, 3], 'load_grid': None, 'update': True } mgp_model = MappedGaussianProcess(gp_model.hyps, gp_model.cutoffs, grid_params, struc_params, mean_only=True, container_only=False, GP=gp_model, lmp_file_name='lmp.mgp') # ------------ create ASE's flare calculator ----------------------- flare_calc = FLARE_Calculator(gp_model, mgp_model, par=True, use_mapping=True) a = 3.855 alpha = 90 super_cell = crystal( ['Ag', 'I'], # Ag, I basis=[(0, 0, 0), (0.5, 0.5, 0.5)], size=(2, 1, 1), cellpar=[a, a, a, alpha, alpha, alpha]) super_cell.positions = positions[-1] super_cell.set_calculator(flare_calc) super_cell.get_forces() stresses = super_cell.calc.results['stresses'] # parse lammps stress lmp_file = open('test_files/stress.lammps') lines = lmp_file.readlines()[9:] for ind, line in enumerate(lines): line = line.split() strs = np.array([float(l) for l in line[1:]]) / 1.60217662e6 assert np.isclose(stresses[ind], strs, rtol=1e-3).all() os.system('rm -r __pycache__') os.system('rm grid3*') os.system('rm -r kv3') os.system('rm lmp.mgp')
def test_lmp_predict(all_lmp, all_gp, all_mgp, bodies, multihyps): """ test the lammps implementation """ # pytest.skip() prefix = f"{bodies}{multihyps}" mgp_model = all_mgp[prefix] gp_model = all_gp[prefix] lmp_calculator = all_lmp[prefix] ase_calculator = FLARE_Calculator(gp_model, mgp_model, par=False, use_mapping=True) # create test structure np.random.seed(1) cell = np.diag(np.array([1, 1, 1])) * 4 nenv = 10 unique_species = gp_model.training_statistics["species"] cutoffs = gp_model.cutoffs struc_test, f = get_random_structure(cell, unique_species, nenv) # build ase atom from struc ase_atoms_flare = struc_test.to_ase_atoms() ase_atoms_flare = FLARE_Atoms.from_ase_atoms(ase_atoms_flare) ase_atoms_flare.calc = ase_calculator ase_atoms_lmp = deepcopy(struc_test).to_ase_atoms() ase_atoms_lmp.calc = lmp_calculator try: lmp_en = ase_atoms_lmp.get_potential_energy() flare_en = ase_atoms_flare.get_potential_energy() lmp_stress = ase_atoms_lmp.get_stress() flare_stress = ase_atoms_flare.get_stress() lmp_forces = ase_atoms_lmp.get_forces() flare_forces = ase_atoms_flare.get_forces() except Exception as e: os.chdir(curr_path) print(e) raise e os.chdir(curr_path) # check that lammps agrees with mgp to within 1 meV/A print("energy", lmp_en - flare_en, flare_en) assert np.isclose(lmp_en, flare_en, atol=1e-3) print("force", lmp_forces - flare_forces, flare_forces) assert np.isclose(lmp_forces, flare_forces, atol=1e-3).all() print("stress", lmp_stress - flare_stress, flare_stress) assert np.isclose(lmp_stress, flare_stress, atol=1e-3).all() # 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)
def flare_calc(): flare_calc_dict = {} for md_engine in md_list: # ---------- create gaussian process model ------------------- gp_model = GaussianProcess( kernel_name='2+3_mc', hyps=[0.1, 1., 0.001, 1, 0.06], cutoffs=(5.0, 5.0), hyp_labels=['sig2', 'ls2', 'sig3', 'ls3', 'noise'], opt_algorithm='BFGS', par=False) # ----------- create mapped gaussian process ------------------ struc_params = { 'species': [1, 2], 'cube_lat': np.eye(3) * 100, 'mass_dict': { '0': 2, '1': 4 } } # grid parameters lower_cut = 2.5 two_cut, three_cut = gp_model.cutoffs grid_num_2 = 8 grid_num_3 = 8 grid_params = { 'bounds_2': [[lower_cut], [two_cut]], 'bounds_3': [[lower_cut, lower_cut, -1], [three_cut, three_cut, 1]], 'grid_num_2': grid_num_2, 'grid_num_3': [grid_num_3, grid_num_3, grid_num_3], 'svd_rank_2': 0, 'svd_rank_3': 0, 'bodies': [2, 3], 'load_grid': None, 'update': True } mgp_model = MappedGaussianProcess(gp_model.hyps, gp_model.cutoffs, grid_params, struc_params, mean_only=False, container_only=False, GP=gp_model, lmp_file_name='lmp.mgp', n_cpus=1) # ------------ create ASE's flare calculator ----------------------- flare_calculator = FLARE_Calculator(gp_model, mgp_model, par=True, use_mapping=True) flare_calc_dict[md_engine] = flare_calculator print(md_engine) yield flare_calc_dict del flare_calc_dict