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_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_predict_efs(two_plus_three_gp): test_structure, _ = \ get_random_structure(np.eye(3), [1, 2], 3) ens, forces, stresses, en_stds, force_stds, stress_stds = \ predict_on_structure_efs(test_structure, two_plus_three_gp) forces_2, force_stds_2 = \ predict_on_structure(test_structure, two_plus_three_gp) ens_p, forces_p, stresses_p, en_stds_p, force_stds_p, stress_stds_p = \ predict_on_structure_efs_par(test_structure, two_plus_three_gp) # Check agreement between efs and standard prediction. assert (np.isclose(forces, forces_2).all()) assert (np.isclose(force_stds, force_stds_2).all()) # Check agreement between serial and parallel efs methods. assert (np.isclose(ens, ens_p).all()) assert (np.isclose(forces, forces_p).all()) assert (np.isclose(stresses, stresses_p).all()) assert (np.isclose(en_stds, en_stds_p).all()) assert (np.isclose(force_stds, force_stds_p).all()) assert (np.isclose(stress_stds, stress_stds_p).all()) # Check that the prediction has been recorded within the structure. assert(np.equal(stress_stds, test_structure.partial_stress_stds).all())
def test_remove_force_data(): """ Train a GP on one fake structure. Store forces from prediction. Add a new fake structure and ensure predictions change; then remove the structure and ensure predictions go back to normal. :return: """ test_structure, forces = get_random_structure(5.0 * np.eye(3), ["H", "Be"], 5) test_structure_2, forces_2 = get_random_structure(5.0 * np.eye(3), ["H", "Be"], 5) gp = GaussianProcess(kernels=["twobody"], cutoffs={"twobody": 0.8}) gp.update_db(test_structure, forces) with raises(ValueError): gp.remove_force_data(1000000) init_forces, init_stds = predict_on_structure(test_structure, gp, write_to_structure=False) init_forces_2, init_stds_2 = predict_on_structure(test_structure_2, gp, write_to_structure=False) # Alternate adding in the entire structure and adding in only one atom. for custom_range in [None, [0]]: # Add in data and ensure the predictions change in reponse gp.update_db(test_structure_2, forces_2, custom_range=custom_range) new_forces, new_stds = predict_on_structure(test_structure, gp, write_to_structure=False) new_forces_2, new_stds_2 = predict_on_structure( test_structure_2, gp, write_to_structure=False) assert not np.array_equal(init_forces, new_forces) assert not np.array_equal(init_forces_2, new_forces_2) assert not np.array_equal(init_stds, new_stds) assert not np.array_equal(init_stds_2, new_stds_2) # Remove that data and test to see that the predictions revert to # what they were previously if custom_range == [0]: popped_strucs, popped_forces = gp.remove_force_data(5) else: popped_strucs, popped_forces = gp.remove_force_data( [5, 6, 7, 8, 9]) for i in range(len(popped_forces)): assert np.array_equal(popped_forces[i], forces_2[i]) assert np.array_equal(popped_strucs[i].structure.positions, test_structure_2.positions) final_forces, final_stds = predict_on_structure( test_structure, gp, write_to_structure=False) final_forces_2, final_stds_2 = predict_on_structure( test_structure_2, gp, write_to_structure=False) assert np.array_equal(init_forces, final_forces) assert np.array_equal(init_stds, final_stds) assert np.array_equal(init_forces_2, final_forces_2) assert np.array_equal(init_stds_2, final_stds_2)