def test_replicate_gp(): """ 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: """ parsed = OtfAnalysis('test_files/VelocityVerlet.log') positions = parsed.position_list forces = parsed.force_list gp_model = parsed.make_gp(kernel_name="two_plus_three_body_mc") structures = parsed.output_md_structures() assert np.isclose(structures[-1].positions, positions[-1]).all() assert np.isclose(structures[-1].forces, forces[-1]).all() final_structure = structures[-1] pred_for, pred_stds = predict_on_structure(final_structure, gp_model) assert np.isclose(final_structure.forces, pred_for, rtol=1e-3).all() assert np.isclose(final_structure.stds, pred_stds, rtol=1e-3).all() set_of_structures = structures[-3:-1] for structure in set_of_structures: pred_for, pred_stds = predict_on_structure(structure, gp_model) assert np.isclose(structure.forces, pred_for, rtol=1e-3, atol=1e-6).all() assert np.isclose(structure.stds, pred_stds, rtol=1e-3, atol=1e-6).all()
def test_replicate_gp(): """ 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: """ os.system('cp test_files/sample_h2_otf.out .') parsed = OtfAnalysis('sample_h2_otf.out') positions = parsed.position_list forces = parsed.force_list gp_model = parsed.make_gp() structures = parsed.output_md_structures() assert np.isclose(structures[-1].positions, positions[-1]).all() assert np.isclose(structures[-1].forces, forces[-1]).all() final_structure = structures[-1] pred_for, pred_stds = predict_on_structure(final_structure, gp_model) assert np.isclose(final_structure.forces, pred_for).all() assert np.isclose(final_structure.stds, pred_stds).all() set_of_structures = structures[-3:-1] for structure in set_of_structures: pred_for, pred_stds = predict_on_structure(structure, gp_model) assert np.isclose(structure.forces, pred_for, atol=1e-6).all() assert np.isclose(structure.stds, pred_stds, atol=1e-6).all() os.system('rm sample_slab_otf.out')
def test_update_L_alpha(): # set up gp model kernel = mc_simple.two_plus_three_body_mc kernel_grad = mc_simple.two_plus_three_body_mc_grad cutoffs = [6.0, 5.0] hyps = np.array([0.001770, 0.183868, -0.001415, 0.372588, 0.026315]) # get an otf traj from file for training data old_otf = OtfAnalysis('test_files/AgI_snippet.out') call_no = 1 cell = old_otf.header['cell'] gp_model = old_otf.make_gp(kernel=kernel, kernel_grad=kernel_grad, call_no=call_no, cutoffs=cutoffs, hyps=hyps) # update database & use update_L_alpha to get ky_mat for n in range(call_no, call_no + 1): positions = old_otf.gp_position_list[n] species = old_otf.gp_species_list[n] atoms = old_otf.gp_atom_list[n] forces = old_otf.gp_force_list[n] struc_curr = Structure(cell, species, positions) gp_model.update_db(struc_curr, forces, custom_range=atoms) gp_model.update_L_alpha() ky_mat_from_update = np.copy(gp_model.ky_mat) # use set_L_alpha to get ky_mat gp_model.set_L_alpha() ky_mat_from_set = np.copy(gp_model.ky_mat) assert (np.all(np.absolute(ky_mat_from_update - ky_mat_from_set)) < 1e-6)
def test_otf_parser_from_checkpt(software): if not os.environ.get(cmd[software], False): pytest.skip(f"{cmd[software]} not found in environment:" " Please install the code " f" and set the {cmd[software]} env. " "variable to point to the executable.") if software == "cp2k": pytest.skip() example = 1 casename = name_list[example] log_name = f"{casename}_otf_{software}" output_name = f"{log_name}.out" otf_traj = OtfAnalysis(output_name) try: replicated_gp = otf_traj.make_gp() except: init_gp = GaussianProcess.from_file(log_name + "_gp.json") replicated_gp = otf_traj.make_gp(init_gp=init_gp) outdir = f"test_outputs_{software}" if not os.path.isdir(outdir): os.mkdir(outdir) for f in os.listdir("./"): if f"{casename}_otf_{software}" in f: shutil.move(f, outdir) cleanup(software, f"{casename}_otf_{software}")
def test_otf_parser(software): if not os.environ.get(cmd[software], False): pytest.skip(f"{cmd[software]} not found in environment:" " Please install the code " f" and set the {cmd[software]} env. " "variable to point to the executable.") example = 1 casename = name_list[example] output_name = f"{casename}_otf_{software}.out" otf_traj = OtfAnalysis(output_name) replicated_gp = otf_traj.make_gp() # TODO: debug cp2k if software == "cp2k": pytest.skip() otf = pytest.my_otf assert otf.dft_count == len(otf_traj.gp_position_list) assert otf.curr_step == len(otf_traj.position_list) + 1 assert otf.dft_count == len(otf_traj.gp_thermostat["temperature"]) assert otf.curr_step == len(otf_traj.thermostat["temperature"]) + 1 if otf_traj.gp_cell_list: assert otf.dft_count == len(otf_traj.gp_cell_list)
def test_otf2xyz(): xyz_file = "h2.xyz" parsed = OtfAnalysis("test_files/sample_h2_otf.out", calculate_energy=True) parsed.to_xyz(xyz_file) xyz_trj = read(xyz_file, index=":") assert np.allclose(xyz_trj[-1].positions[0, 0], 2.2794) assert np.allclose(xyz_trj[-2].get_forces()[-1, 2], 0.0000) os.system("rm h2.xyz")
def test_output_md_structures(): parsed = OtfAnalysis('test_files/VelocityVerlet.log') positions = parsed.position_list forces = parsed.force_list structures = parsed.output_md_structures() assert np.isclose(structures[-1].positions, positions[-1]).all() assert np.isclose(structures[-1].forces, forces[-1]).all()
def test_output_md_structures(): os.system('cp test_files/sample_slab_otf.out .') parsed = OtfAnalysis('sample_slab_otf.out') positions = parsed.position_list forces = parsed.force_list structures = parsed.output_md_structures() assert np.isclose(structures[-1].positions, positions[-1]).all() assert np.isclose(structures[-1].forces, forces[-1]).all()
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_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 test_md_parser(): """ Test the capability of otf parser to read MD info :return: """ os.system('cp test_files/sample_slab_otf.out .') parsed = OtfAnalysis('sample_slab_otf.out') pos1 = 10.09769665 assert(pos1 == parsed.position_list[0][0][2]) assert(len(parsed.position_list[0]) == 28)
def test_md_parser(): """ Test the capability of otf parser to read MD info :return: """ parsed = OtfAnalysis('test_files/VelocityVerlet.log') pos1 = -0.172516 assert (pos1 == parsed.position_list[0][0][2]) assert (len(parsed.position_list[0]) == 4)
def test_md_parser(): """ Test the capability of otf parser to read MD info :return: """ os.system("cp test_files/sample_slab_otf.out .") parsed = OtfAnalysis("sample_slab_otf.out") pos1 = 10.09769665 assert pos1 == parsed.position_list[0][0][2] assert len(parsed.position_list[0]) == 28 os.system("rm sample_slab_otf.out")
def test_parse_header(): header_dict = OtfAnalysis('test_files/VelocityVerlet.log').header assert header_dict['frames'] == 0 assert header_dict['atoms'] == 4 assert header_dict['species_set'] == {'Ag', 'I'} assert header_dict['dt'] == .001 assert header_dict['kernel_name'] == 'two_plus_three_body_mc' assert header_dict['n_hyps'] == 5 assert header_dict['algo'] == 'BFGS' assert np.equal( header_dict['cell'], np.array([[7.71, 0., 0.], [0., 3.855, 0.], [0., 0., 3.855]])).all()
def test_parse_header(): os.system('cp test_files/sample_slab_otf.out .') header_dict = OtfAnalysis('sample_slab_otf.out').header assert header_dict['frames'] == 5000 assert header_dict['atoms'] == 28 assert header_dict['species_set'] == {'Al'} assert header_dict['dt'] == .001 assert header_dict['kernel'] == 'two_plus_three_body' assert header_dict['n_hyps'] == 5 assert header_dict['algo'] == 'BFGS' assert np.equal(header_dict['cell'], np.array([[8.59135, 0., 0.], [4.29567, 7.44033, 0.], [0., 0., 26.67654]])).all()
def test_parse_header(): os.system("cp test_files/sample_slab_otf.out .") header_dict = OtfAnalysis("sample_slab_otf.out").header assert header_dict["frames"] == 5000 assert header_dict["atoms"] == 28 assert header_dict["species_set"] == {"Al"} assert header_dict["dt"] == 0.001 assert header_dict["kernel_name"] == "two_plus_three_body" assert header_dict["n_hyps"] == 5 assert header_dict["algo"] == "BFGS" assert np.equal( header_dict["cell"], np.array([[8.59135, 0.0, 0.0], [4.29567, 7.44033, 0.0], [0.0, 0.0, 26.67654]]), ).all() os.system("rm sample_slab_otf.out")
def test_gp_parser(): """ Test the capability of otf parser to read GP/DFT info :return: """ parsed = OtfAnalysis('test_files/VelocityVerlet.log') assert (parsed.gp_species_list == [['Ag', 'I'] * 2]) gp_positions = parsed.gp_position_list assert len(gp_positions) == 1 pos1 = 1.819218 pos2 = -0.141231 assert (pos1 == gp_positions[0][-1][1]) assert (pos2 == gp_positions[-1][0][2]) force1 = -0.424080 force2 = 0.498037 assert (force1 == parsed.gp_force_list[0][-1][1]) assert (force2 == parsed.gp_force_list[-1][0][2])
def test_gp_parser(): """ Test the capability of otf parser to read GP/DFT info :return: """ os.system('cp test_files/sample_slab_otf.out .') parsed = OtfAnalysis('sample_slab_otf.out') assert (parsed.gp_species_list == [['Al']*28] * 4) gp_positions = parsed.gp_position_list assert len(gp_positions) == 4 pos1 = 1.50245891 pos2 = 10.06179079 assert(pos1 == gp_positions[0][-1][1]) assert(pos2 == gp_positions[-1][0][2]) force1 = 0.29430943 force2 = -0.02350709 assert(force1 == parsed.gp_force_list[0][-1][1]) assert(force2 == parsed.gp_force_list[-1][0][2])
def test_gp_parser(): """ Test the capability of otf parser to read GP/DFT info :return: """ os.system("cp test_files/sample_slab_otf.out .") parsed = OtfAnalysis("sample_slab_otf.out") assert parsed.gp_species_list == [["Al"] * 28] * 4 gp_positions = parsed.gp_position_list assert len(gp_positions) == 4 pos1 = 1.50245891 pos2 = 10.06179079 assert pos1 == gp_positions[0][-1][1] assert pos2 == gp_positions[-1][0][2] force1 = 0.29430943 force2 = -0.02350709 assert force1 == parsed.gp_force_list[0][-1][1] assert force2 == parsed.gp_force_list[-1][0][2] os.system("rm sample_slab_otf.out")
def test_otf_md(md_engine, md_params, super_cell, flare_calc, qe_calc, write_model): np.random.seed(12345) flare_calculator = flare_calc[md_engine] output_name = f"{md_engine}_{write_model}" # set up OTF MD engine otf_params = { "init_atoms": [0, 1, 2, 3], "output_name": output_name, "std_tolerance_factor": 1.0, "max_atoms_added": len(super_cell.positions), "freeze_hyps": 10, "write_model": write_model, } # 'use_mapping': flare_calculator.use_mapping} md_kwargs = md_params[md_engine] # intialize velocity temperature = md_params["temperature"] MaxwellBoltzmannDistribution(super_cell, temperature * units.kB) Stationary(super_cell) # zero linear momentum ZeroRotation(super_cell) # zero angular momentum super_cell.calc = flare_calculator test_otf = ASE_OTF( super_cell, timestep=1 * units.fs, number_of_steps=number_of_steps, dft_calc=qe_calc, md_engine=md_engine, md_kwargs=md_kwargs, trajectory=f"{output_name}_otf.traj", **otf_params, ) # TODO: test if mgp matches gp # TODO: see if there's difference between MD timestep & OTF timestep test_otf.run() # Check that the GP forces change. otf_traj = OtfAnalysis(output_name + ".out") comp1 = otf_traj.force_list[-2][1, 0] comp2 = otf_traj.force_list[-1][1, 0] assert comp1 != comp2 for f in glob.glob("scf*.pw*"): os.remove(f) for f in glob.glob("*.npy"): os.remove(f) for f in glob.glob("kv3*"): shutil.rmtree(f) for f in glob.glob("otf_data"): shutil.rmtree(f, ignore_errors=True) for f in glob.glob("out"): shutil.rmtree(f, ignore_errors=True) for f in os.listdir("./"): if ".mgp" in f or ".var" in f: os.remove(f) if "slurm" in f: os.remove(f)
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')