Ejemplo n.º 1
0
    def GenGrid(self, GP, bond_struc, processes=mp.cpu_count()):
        '''
        generate grid data of mean prediction and L^{-1}k* for each triplet
        default implemented in a parallelized style
        '''
        processes = mp.cpu_count()
        nop = self.grid_num
        bond_lengths = np.linspace(self.l_bound, self.u_bound, nop)
        bond_means = np.zeros([nop])
        bond_vars = np.zeros([nop, nop])

        env1 = env.AtomicEnvironment(bond_struc, 0, self.cutoffs)
        env2 = env.AtomicEnvironment(bond_struc, 0, self.cutoffs)

        pool_list = [(i, bond_lengths[i], bond_lengths, GP, env1, env2)
                     for i in range(nop)]
        pool = mp.Pool(processes=processes)
        A_list = pool.starmap(self._GenGrid_inner, pool_list)
        pool.close()
        pool.join()

        A_list.sort(key=lambda x: x[0])
        for b1 in range(nop):
            bond_means[b1] = A_list[b1][1]
            bond_vars[b1, :] = A_list[b1][2]

        return bond_means, bond_vars
Ejemplo n.º 2
0
def generate_mb_envs_pos(positions0,
                         species_1,
                         cutoffs,
                         cell,
                         delt,
                         d1,
                         mask=None):

    positions = [positions0]

    noa = len(positions0)

    positions_2 = deepcopy(positions0)
    positions_2[0][d1 - 1] = delt
    positions += [positions_2]

    positions_3 = deepcopy(positions[0])
    positions_3[0][d1 - 1] = -delt
    positions += [positions_3]

    test_struc = []
    for i in range(3):
        test_struc += [struc.Structure(cell, species_1, positions[i])]

    env_0 = []
    env_p = []
    env_m = []
    for i in range(noa):
        env_0 += [env.AtomicEnvironment(test_struc[0], i, cutoffs)]
        env_p += [env.AtomicEnvironment(test_struc[1], i, cutoffs)]
        env_m += [env.AtomicEnvironment(test_struc[2], i, cutoffs)]

    return [env_0, env_p, env_m]
Ejemplo n.º 3
0
def test_three_body_force_en():
    """Check that the analytical force/en kernel matches finite difference of
    energy kernel."""

    # create env 1
    delt = 1e-8
    cell = np.eye(3)
    cutoffs = np.array([1, 1])

    positions_1 = [
        np.array([0., 0., 0.]),
        np.array([random(), random(), random()]),
        np.array([random(), random(), random()])
    ]
    positions_2 = deepcopy(positions_1)
    positions_2[0][0] = delt

    species_1 = [1, 2, 1]
    atom_1 = 0
    test_structure_1 = struc.Structure(cell, species_1, positions_1)
    test_structure_2 = struc.Structure(cell, species_1, positions_2)

    env1_1 = env.AtomicEnvironment(test_structure_1, atom_1, cutoffs)
    env1_2 = env.AtomicEnvironment(test_structure_2, atom_1, cutoffs)

    # create env 2
    positions_1 = [
        np.array([0., 0., 0.]),
        np.array([random(), random(), random()]),
        np.array([random(), random(), random()])
    ]

    species_2 = [1, 1, 2]
    atom_2 = 0
    test_structure_1 = struc.Structure(cell, species_2, positions_1)
    env2 = env.AtomicEnvironment(test_structure_1, atom_2, cutoffs)

    sig = random()
    ls = random()
    d1 = 1

    hyps = np.array([sig, ls])

    # check force kernel
    calc1 = en.three_body_en(env1_2, env2, hyps, cutoffs)
    calc2 = en.three_body_en(env1_1, env2, hyps, cutoffs)

    kern_finite_diff = (calc1 - calc2) / delt
    kern_analytical = en.three_body_force_en(env1_1, env2, d1, hyps, cutoffs)

    tol = 1e-4
    assert (np.isclose(-kern_finite_diff / 3, kern_analytical, atol=tol))
Ejemplo n.º 4
0
def test_three_body_grad():
    # create env 1
    cell = np.eye(3)
    cutoffs = np.array([1, 1])

    positions_1 = [np.array([0., 0., 0.]),
                   np.array([random(), random(), random()]),
                   np.array([random(), random(), random()])]

    species_1 = [1, 2, 1]
    atom_1 = 0
    test_structure_1 = struc.Structure(cell, species_1, positions_1)
    env1 = env.AtomicEnvironment(test_structure_1, atom_1, cutoffs)

    # create env 2
    positions_1 = [np.array([0., 0., 0.]),
                   np.array([random(), random(), random()]),
                   np.array([random(), random(), random()])]

    species_2 = [1, 1, 2]
    atom_2 = 0
    test_structure_1 = struc.Structure(cell, species_2, positions_1)
    env2 = env.AtomicEnvironment(test_structure_1, atom_2, cutoffs)

    sig = random()
    ls = random()
    d1 = randint(1, 3)
    d2 = randint(1, 3)

    hyps = np.array([sig, ls])

    grad_test = en.three_body_grad(env1, env2, d1, d2, hyps, cutoffs)

    delta = 1e-8
    new_sig = sig + delta
    new_ls = ls + delta

    sig_derv_brute = (en.three_body(env1, env2, d1, d2,
                                    np.array([new_sig, ls]),
                                    cutoffs) -
                      en.three_body(env1, env2, d1, d2,
                                    hyps, cutoffs)) / delta

    l_derv_brute = (en.three_body(env1, env2, d1, d2,
                                  np.array([sig, new_ls]),
                                  cutoffs) -
                    en.three_body(env1, env2, d1, d2,
                                  hyps, cutoffs)) / delta

    tol = 1e-4
    assert(np.isclose(grad_test[1][0], sig_derv_brute, atol=tol))
    assert(np.isclose(grad_test[1][1], l_derv_brute, atol=tol))
Ejemplo n.º 5
0
    def GenGrid(self, GP, bond_struc, processes=mp.cpu_count()):
        '''
        generate grid data of mean prediction and L^{-1}k* for each triplet
         implemented in a parallelized style
        '''
        # ------ change GP kernel to 3 body ------
        original_kernel = GP.kernel
        original_hyps = np.copy(GP.hyps)
        GP.kernel = three_body_mc
        GP.hyps = GP.hyps[-3:]

        # ------ construct grids ------
        nop = self.grid_num[0]
        noa = self.grid_num[2]
        bond_lengths = np.linspace(self.l_bound[0], self.u_bound[0], nop)
        angles = np.linspace(self.l_bound[2], self.u_bound[2], noa)
        bond_means = np.zeros([nop, nop, noa])
        bond_vars = np.zeros([nop, nop, noa, len(GP.alpha)])
        env12 = env.AtomicEnvironment(bond_struc, 0, self.cutoffs)

        pool_list = [(i, angles[i], bond_lengths, GP, env12)
                     for i in range(noa)]
        pool = mp.Pool(processes=processes)
        A_list = pool.map(self._GenGrid_inner, pool_list)
        for a12 in range(noa):
            bond_means[:, :, a12] = A_list[a12][0]
            bond_vars[:, :, a12, :] = A_list[a12][1]
        pool.close()
        pool.join()

        # ------ change back to original GP ------
        GP.hyps = original_hyps
        GP.kernel = original_kernel

        return bond_means, bond_vars
Ejemplo n.º 6
0
def force_envs(strucs):
    """Perturb atom 0 in both structures up and down and in all directions."""

    signs = [1, -1]
    dims = [0, 1, 2]
    force_envs = []
    for structure in strucs:
        sign_envs_curr = []
        for sign in signs:
            dim_envs_curr = []
            for dim in dims:
                positions_pert = np.copy(structure.positions)
                positions_pert[0, dim] += delta * sign
                struc_pert = struc.Structure(structure.cell,
                                             structure.coded_species,
                                             positions_pert)
                atom_envs = []
                for n in range(structure.nat):
                    env_curr = env.AtomicEnvironment(struc_pert, n, cutoffs)
                    atom_envs.append(env_curr)
                dim_envs_curr.append(atom_envs)
            sign_envs_curr.append(dim_envs_curr)
        force_envs.append(sign_envs_curr)

    yield force_envs
Ejemplo n.º 7
0
def predict_atom_diag_var_2b(atom_env, gp_model, force_kernel):
    bond_array = atom_env.bond_array_2
    ctype = atom_env.ctype

    var = 0
    for m in range(bond_array.shape[0]):
        ri1 = bond_array[m, 0]
        ci1 = bond_array[m, 1:]
        etype1 = atom_env.etypes[m]

        # build up a struc of triplet for prediction
        cell = np.eye(3) * 100
        positions = np.array([np.zeros(3), ri1 * ci1])
        species = np.array([ctype, etype1])
        spc_struc = struc.Structure(cell, species, positions)
        spc_struc.coded_species = np.array(species)
        env12 = env.AtomicEnvironment(spc_struc, 0, gp_model.cutoffs)

        coord = np.copy(env12.bond_array_2[0, 1:])
        # env12.bond_array_2[0, 1:] = np.array([1., 0., 0.])
        if force_kernel:
            v12 = np.zeros(3)
            for d in range(3):
                _, v12[d] = gp_model.predict(env12, d + 1)
            print("v12", np.sqrt(v12), coord)
        else:
            _, v12 = gp_model.predict_local_energy_and_var(env12)

        var += np.sqrt(v12)

    var = var**2
    return var
Ejemplo n.º 8
0
def test_predict(all_gp, all_mgp, bodies):
    """
    test the predict for mc_simple kernel
    """

    gp_model = all_gp[f'{bodies}']
    mgp_model = all_mgp[f'{bodies}']
    atom_id = 1

    nenv = 10
    cell = np.eye(3)
    cutoffs = gp_model.cutoffs
    unique_species = gp_model.training_data[0].species
    struc_test, f = get_random_structure(cell, unique_species, nenv)
    test_envi = env.AtomicEnvironment(struc_test, atom_id, cutoffs)

    mgp_pred = mgp_model.predict(test_envi, mean_only=True)

    # check mgp is within 1 meV/A of the gp
    for s in range(3):
        gp_pred_x = gp_model.predict(test_envi, s + 1)
        print(mgp_pred, gp_pred_x)
        assert(np.abs(mgp_pred[0][s] - gp_pred_x[0]) < 1e-3), \
                f"{bodies} body mapping is wrong"

    clean()
Ejemplo n.º 9
0
def test_predict(all_gp, all_mgp, bodies, multihyps):
    """
    test the predict for mc_simple kernel
    """

    # multihyps = False
    gp_model = all_gp[f'{bodies}{multihyps}']
    mgp_model = all_mgp[f'{bodies}{multihyps}']

    nenv = 10
    cell = np.eye(3)
    cutoffs = gp_model.cutoffs
    unique_species = gp_model.training_data[0].species
    struc_test, f = get_random_structure(cell, unique_species, nenv)
    test_envi = env.AtomicEnvironment(struc_test, 1, cutoffs)

    gp_pred_en = gp_model.predict_local_energy(test_envi)
    gp_pred_x = gp_model.predict(test_envi, 1)
    mgp_pred = mgp_model.predict(test_envi, mean_only=True)

    # check mgp is within 1 meV/A of the gp
    assert(np.abs(mgp_pred[3] - gp_pred_en) < 1e-3), \
            f"{bodies} body energy mapping is wrong"
    assert(np.abs(mgp_pred[0][0] - gp_pred_x[0]) < 1e-3), \
            f"{bodies} body mapping is wrong"

    clean()
Ejemplo n.º 10
0
 def predict_on_structure(self):
     for n in range(self.structure.nat):
         chemenv = env.AtomicEnvironment(self.structure, n, self.gp.cutoffs)
         for i in range(3):
             force, var = self.gp.predict(chemenv, i + 1)
             self.structure.forces[n][i] = float(force)
             self.structure.stds[n][i] = np.sqrt(np.abs(var))
Ejemplo n.º 11
0
def test_2_plus_3_body(otf_object, structure, params):
    # 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=2)
    gp_model.par = True
    gp_model.hyp_labels = ['sig2', 'ls2', 'sig3', 'ls3', 'noise']

    # create MGP
    grid_params = params['grid']
    grid_params['bodies'] = [2, 3]
    struc_params = params['struc']
    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='AgI_Molten_15.txt')

    # test if MGP prediction matches GP
    atom = 0
    environ = env.AtomicEnvironment(structure, atom, gp_model.cutoffs)

    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)
Ejemplo n.º 12
0
def predict_struc_diag_var(struc, gp_model):
    variance = np.zeros((struc.nat, 3))
    for atom in range(struc.nat):
        atom_env = env.AtomicEnvironment(struc, atom, gp_model.cutoffs)
        var = predict_atom_diag_var(atom_env, gp_model)
        variance[atom, :] = var
    return variance
Ejemplo n.º 13
0
def another_env(cutoffs, delt):

    cell = 10.0 * np.eye(3)

    # atomic structure 1
    pos_1 = np.vstack([[0, 0, 0], 0.1 * random([3, 3])])
    pos_1[1, 1] += 1
    pos_1[2, 0] += 1
    pos_1[3, :2] += 1
    pos_2 = deepcopy(pos_1)
    pos_2[0][0] = delt
    pos_3 = deepcopy(pos_1)
    pos_3[0][0] = -delt

    species_1 = [1, 1, 1, 1]

    test_structure_1 = struc.Structure(cell, species_1, pos_1)
    test_structure_2 = struc.Structure(cell, species_1, pos_2)
    test_structure_3 = struc.Structure(cell, species_1, pos_3)

    # atom 0, original position
    env1_1_0 = env.AtomicEnvironment(test_structure_1, 0, cutoffs)
    # atom 0, 0 perturbe along x
    env1_2_0 = env.AtomicEnvironment(test_structure_2, 0, cutoffs)
    # atom 1, 0 perturbe along x
    env1_2_1 = env.AtomicEnvironment(test_structure_2, 1, cutoffs)
    # atom 2, 0 perturbe along x
    env1_2_2 = env.AtomicEnvironment(test_structure_2, 2, cutoffs)

    # atom 0, 0 perturbe along -x
    env1_3_0 = env.AtomicEnvironment(test_structure_3, 0, cutoffs)
    # atom 1, 0 perturbe along -x
    env1_3_1 = env.AtomicEnvironment(test_structure_3, 1, cutoffs)
    # atom 2, 0 perturbe along -x
    env1_3_2 = env.AtomicEnvironment(test_structure_3, 2, cutoffs)

    # create env 2
    pos_1 = np.vstack([[0, 0, 0], 0.1 * random([3, 3])])
    pos_1[1, 1] += 1
    pos_1[2, 0] += 1
    pos_1[3, :2] += 1
    pos_2 = deepcopy(pos_1)
    pos_2[0][0] = delt
    pos_3 = deepcopy(pos_1)
    pos_3[0][0] = -delt

    species_2 = [1, 2, 2, 1]

    test_structure_1 = struc.Structure(cell, species_2, pos_1)

    env2_1_0 = env.AtomicEnvironment(test_structure_1, 0, cutoffs)

    return env1_1_0, env1_2_0, env1_3_0, \
           env1_2_1, env1_3_1, env1_2_2, env1_3_2, env2_1_0
Ejemplo n.º 14
0
    def predict_on_atom(self, atom):
        chemenv = env.AtomicEnvironment(self.structure, atom, self.gp.cutoffs)
        comps = []
        stds = []
        # predict force components and standard deviations
        for i in range(3):
            force, var = self.gp.predict(chemenv, i + 1)
            comps.append(float(force))
            stds.append(np.sqrt(np.abs(var)))

        return comps, stds
Ejemplo n.º 15
0
def struc_envs(strucs):
    """Store the environments of the random structures."""

    struc_envs = []
    for structure in strucs:
        envs_curr = []
        for n in range(structure.nat):
            env_curr = env.AtomicEnvironment(structure, n, cutoffs)
            envs_curr.append(env_curr)
        struc_envs.append(envs_curr)

    yield struc_envs
Ejemplo n.º 16
0
    def predict_on_structure_mgp(self):  # changed
        """
        Assign forces to self.structure based on self.gp
        """

        output.write_to_output('\npredict with mapping:\n', self.output_name)
        for n in range(self.structure.nat):
            chemenv = env.AtomicEnvironment(self.structure, n, self.gp.cutoffs)
            force, var = self.mgp_model.predict(chemenv)
            self.structure.forces[n][:] = force
            self.structure.stds[n][:] = np.sqrt(np.absolute(var))
        self.structure.dft_forces = False
Ejemplo n.º 17
0
def get_grid_env(GP, species, bodies):
    if isinstance(GP.cutoffs, dict):
        max_cut = np.max(list(GP.cutoffs.values()))
    else:
        max_cut = np.max(GP.cutoffs)
    big_cell = np.eye(3) * 100
    positions = [[(i + 1) / (bodies + 1) * 0.1, 0, 0] for i in range(bodies)]
    grid_struc = struc.Structure(big_cell, species, positions)
    grid_env = env.AtomicEnvironment(grid_struc,
                                     0,
                                     GP.cutoffs,
                                     cutoffs_mask=GP.hyps_mask)

    return grid_env
Ejemplo n.º 18
0
def predict_atom_diag_var_3b(atom_env, gp_model, force_kernel):
    bond_array = atom_env.bond_array_3
    triplets = atom_env.triplet_counts
    cross_bond_inds = atom_env.cross_bond_inds
    cross_bond_dists = atom_env.cross_bond_dists
    ctype = atom_env.ctype

    var = 0
    pred_dict = {}
    for m in range(bond_array.shape[0]):
        ri1 = bond_array[m, 0]
        ci1 = bond_array[m, 1:]
        etype1 = atom_env.etypes[m]

        for n in range(triplets[m]):
            ind1 = cross_bond_inds[m, m + n + 1]
            ri2 = bond_array[ind1, 0]
            ci2 = bond_array[ind1, 1:]
            etype2 = atom_env.etypes[ind1]

            ri3 = cross_bond_dists[m, m + n + 1]

            # build up a struc of triplet for prediction
            cell = np.eye(3) * 100
            positions = np.array([np.zeros(3), ri1 * ci1, ri2 * ci2])
            species = np.array([ctype, etype1, etype2])
            spc_struc = struc.Structure(cell, species, positions)
            spc_struc.coded_species = np.array(species)
            env12 = env.AtomicEnvironment(spc_struc, 0, gp_model.cutoffs)

            #            env12.bond_array_3[0, 1:] = np.array([1., 0., 0.])
            #            env12.bond_array_3[1, 1:] = np.array([0., 0., 0.])
            if force_kernel:
                v12 = np.zeros(3)
                for d in range(3):
                    _, v12[d] = gp_model.predict(env12, d + 1)
                print("v12", np.sqrt(v12), env12.ctype, env12.etypes)
            else:
                _, v12 = gp_model.predict_local_energy_and_var(env12)

            spc = f"{env12.ctype}_{env12.etypes[0]}_{env12.etypes[1]}"
            if spc in pred_dict:
                pred_dict[spc] += np.sqrt(v12)
            else:
                pred_dict[spc] = np.sqrt(v12)

            var += np.sqrt(v12)
    var = var**2
    print(pred_dict)
    return var
Ejemplo n.º 19
0
def stress_envs(strucs):
    """Strain both structures up and down and in all directions."""

    stress_envs = []
    signs = [1, -1]
    for structure in strucs:
        sign_envs_curr = []
        for sign in signs:
            strain_envs_curr = []
            for m in range(3):
                for n in range(m, 3):
                    cell_pert = np.copy(structure.cell)
                    positions_pert = np.copy(structure.positions)

                    # Strain the cell.
                    for p in range(3):
                        cell_pert[p, m] += structure.cell[p, n] * delta * sign

                    # Strain the positions.
                    for k in range(structure.nat):
                        positions_pert[
                            k, m] += structure.positions[k, n] * delta * sign

                    struc_pert = struc.Structure(cell_pert,
                                                 structure.coded_species,
                                                 positions_pert)

                    atom_envs = []
                    for q in range(structure.nat):
                        env_curr = env.AtomicEnvironment(
                            struc_pert, q, cutoffs)
                        atom_envs.append(env_curr)
                    strain_envs_curr.append(atom_envs)
            sign_envs_curr.append(strain_envs_curr)
        stress_envs.append(sign_envs_curr)

    yield stress_envs
Ejemplo n.º 20
0
    def GenGrid_svd(self, GP, bond_struc, processes=mp.cpu_count()):
    
        '''
        generate grid data of mean prediction and L^{-1}k* for each triplet
         implemented in a parallelized style
        '''

        # ------ change GP kernel to 2 body ------
        GP.kernel = two_body
        original_cutoffs = np.copy(GP.cutoffs)
        GP.cutoffs = [GP.cutoffs[0]]
        original_hyps = np.copy(GP.hyps)
        GP.hyps = [GP.hyps[0], GP.hyps[1], GP.hyps[-1]]

        # ------ construct grids ------
        nop = self.grid_num
        bond_lengths = np.linspace(self.l_bound[0], self.u_bound[0], nop)
        bond_means = np.zeros([nop])
        bond_vars = np.zeros([nop, len(GP.alpha)])
        env12 = env.AtomicEnvironment(bond_struc, 0, self.cutoffs)
        
        pool_list = [(i, bond_lengths, GP, env12)\
                     for i in range(nop)]
        pool = mp.Pool(processes=processes)
        A_list = pool.map(self._GenGrid_svd_inner, pool_list)
        for p in range(nop):
            bond_means[p] = A_list[p][0]
            bond_vars[p, :] = A_list[p][1]
        pool.close()
        pool.join()

        # ------ change back original GP ------
        GP.cutoffs = original_cutoffs
        GP.hyps = original_hyps
        GP.kernel = two_plus_three_body
       
        return bond_means, bond_vars
Ejemplo n.º 21
0
def generate_envs(cutoffs, delta):
    """
    create environment with perturbation on
    direction i
    """
    # create env 1
    # perturb the x direction of atom 0 for +- delta
    cell = np.eye(3) * np.max(cutoffs + 0.1)
    atom_1 = 0
    pos_1 = np.vstack([[0, 0, 0], random([3, 3])])
    pos_2 = deepcopy(pos_1)
    pos_2[0][0] = delta
    pos_3 = deepcopy(pos_1)
    pos_3[0][0] = -delta

    species_1 = [1, 2, 1, 1]  # , 1, 1, 2, 1, 2]
    test_structure_1 = struc.Structure(cell, species_1, pos_1)
    test_structure_2 = struc.Structure(cell, species_1, pos_2)
    test_structure_3 = struc.Structure(cell, species_1, pos_3)

    env1_1 = env.AtomicEnvironment(test_structure_1, atom_1, cutoffs)
    env1_2 = env.AtomicEnvironment(test_structure_2, atom_1, cutoffs)
    env1_3 = env.AtomicEnvironment(test_structure_3, atom_1, cutoffs)

    # create env 2
    # perturb the y direction
    pos_1 = np.vstack([[0, 0, 0], random([3, 3])])
    pos_2 = deepcopy(pos_1)
    pos_2[0][1] = delta
    pos_3 = deepcopy(pos_1)
    pos_3[0][1] = -delta

    atom_2 = 0
    species_2 = [1, 1, 2, 1]  #, 2, 1, 2, 2, 2]

    test_structure_1 = struc.Structure(cell, species_2, pos_1)
    test_structure_2 = struc.Structure(cell, species_2, pos_2)
    test_structure_3 = struc.Structure(cell, species_2, pos_3)

    env2_1 = env.AtomicEnvironment(test_structure_1, atom_2, cutoffs)
    env2_2 = env.AtomicEnvironment(test_structure_2, atom_2, cutoffs)
    env2_3 = env.AtomicEnvironment(test_structure_3, atom_2, cutoffs)

    return env1_1, env1_2, env1_3, env2_1, env2_2, env2_3
Ejemplo n.º 22
0
def generate_envs(cutoffs, delta):
    # create env 1
    cell = np.eye(3)

    positions_1 = np.vstack([[0, 0, 0], random([3, 3])])
    positions_2 = np.copy(positions_1)
    positions_2[0][0] = delta
    positions_3 = np.copy(positions_1)
    positions_3[0][0] = -delta

    species_1 = [1, 2, 1, 1, 1, 1, 2, 1, 2]
    atom_1 = 0
    test_structure_1 = struc.Structure(cell, species_1, positions_1)
    test_structure_2 = struc.Structure(cell, species_1, positions_2)
    test_structure_3 = struc.Structure(cell, species_1, positions_3)

    env1_1 = env.AtomicEnvironment(test_structure_1, atom_1, cutoffs)
    env1_2 = env.AtomicEnvironment(test_structure_2, atom_1, cutoffs)
    env1_3 = env.AtomicEnvironment(test_structure_3, atom_1, cutoffs)

    # create env 2
    positions_1 = np.vstack([[0, 0, 0], random([3, 3])])
    positions_2 = np.copy(positions_1)
    positions_2[0][1] = delta
    positions_3 = np.copy(positions_1)
    positions_3[0][1] = -delta

    atom_2 = 0
    species_2 = [1, 1, 2, 1, 2, 1, 2, 2, 2]

    test_structure_1 = struc.Structure(cell, species_2, positions_1)
    test_structure_2 = struc.Structure(cell, species_2, positions_2)
    test_structure_3 = struc.Structure(cell, species_2, positions_3)

    env2_1 = env.AtomicEnvironment(test_structure_1, atom_2, cutoffs)
    env2_2 = env.AtomicEnvironment(test_structure_2, atom_2, cutoffs)
    env2_3 = env.AtomicEnvironment(test_structure_3, atom_2, cutoffs)

    return env1_1, env1_2, env1_3, env2_1, env2_2, env2_3
Ejemplo n.º 23
0
    #        mff_pred[atom, :] = mff_f
    #        mff_var[atom, :] = mff_v
    #        var_err += np.mean(np.absolute(mff_v-variances[atom, :]))
    ##        print(env_curr.ctype, mff_v, variances[atom])

    store_predictions.append(predictions)
    store_mffpred.append(mff_pred)
    store_forces.append(forces)

    # test a toy case for testing lammps
    positions = np.array([[0, 0, 0], [0, 0, 1.76339], [0, 1.41071, 0]])
    species_list = ['H', 'C', 'H']
    new_cell = np.eye(3) * 20
    toy_struc = struc.Structure(new_cell, species_list, positions)
    for atom in range(3):
        atom_env = env.AtomicEnvironment(toy_struc, atom, cutoffs)
        pred_f, pred_v = mff_model.predict(atom_env, mean_only=True)
        print(pred_f)

# ----------------- save coeffs ---------------------
if 2 in grid_params['bodies']:
    for ind, spc in enumerate(mff_model.spcs[0]):
        save_name = '{}{}_{}'.format(spc[0], spc[1], 2)
        np.save(save_name, mff_model.maps_2[ind].mean.model.__coeffs__)

if 3 in grid_params['bodies']:
    for ind, spc in enumerate(mff_model.spcs[1]):
        save_name = '{}{}{}_{}'.format(spc[0], spc[1], spc[2], 3)
        np.save(save_name, mff_model.maps_3[ind].mean.model.__coeffs__)

# ----------------- save predictions and ground truth
Ejemplo n.º 24
0
energies = np.zeros(len(lammps_files))
"""Print forces and GP standard deviations to make sure the values look reasonable."""
out_f = open('gp_f.txt', 'w')

# loop over NEB structures
for count, lammps_file in enumerate(tqdm(lammps_files)):
    """The lammps_parser function, defined in dump_parser.py in this directory, extracts the coordinates from a dump file and converts the BOX_BOUNDS output into an array of Bravais lattice vectors."""
    positions, cell = lammps_parser(lammps_file)
    structure = struc.Structure(cell, species, positions)

    # loop over atoms in the structure
    local_energies = np.zeros(nat)
    for n in range(structure.nat):
        """Construct an atomic environment object, which stores all the interatomic distances within 2- and 3-body cutoff spheres that are needed to compute the local energy assigned to the atom."""
        chemenv = env.AtomicEnvironment(structure, n, gp_model.cutoffs)
        for i in range(3):
            force, var = gp_model.predict(chemenv, i + 1)
            structure.forces[n][i] = float(force)
            structure.stds[n][i] = np.sqrt(np.abs(var))
            local_energies[n] = gp_model.predict_local_energy(chemenv)

    out_f.write('Image = ' + str(count) + '\n')
    out_f.write('forces:')
    out_f.write(str(structure.forces))
    out_f.write('\n')
    out_f.write('stds:')
    out_f.write(str(structure.stds))
    out_f.write('\n')
    """Sum up the local energies to get the total energy of the structure."""
    total_energy = np.sum(local_energies)
Ejemplo n.º 25
0
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()
Ejemplo n.º 26
0
def test_two_plus_three_body_force():
    """Check that the analytical force kernel matches finite difference of
    energy kernel."""

    # create env 1
    delt = 1e-5
    cell = np.eye(3)
    cutoffs = np.array([1, 0.9])

    positions_1 = [np.array([0., 0., 0.]),
                   np.array([random(), random(), random()]),
                   np.array([random(), random(), random()])]
    positions_2 = deepcopy(positions_1)
    positions_2[0][0] = delt

    positions_3 = deepcopy(positions_1)
    positions_3[0][0] = -delt

    species_1 = [1, 2, 1]
    atom_1 = 0
    test_structure_1 = struc.Structure(cell, species_1, positions_1)
    test_structure_2 = struc.Structure(cell, species_1, positions_2)
    test_structure_3 = struc.Structure(cell, species_1, positions_3)

    env1_1 = env.AtomicEnvironment(test_structure_1, atom_1, cutoffs)
    env1_2 = env.AtomicEnvironment(test_structure_2, atom_1, cutoffs)
    env1_3 = env.AtomicEnvironment(test_structure_3, atom_1, cutoffs)

    # create env 2
    positions_1 = [np.array([0., 0., 0.]),
                   np.array([random(), random(), random()]),
                   np.array([random(), random(), random()])]
    positions_2 = deepcopy(positions_1)
    positions_2[0][1] = delt
    positions_3 = deepcopy(positions_1)
    positions_3[0][1] = -delt

    species_2 = [1, 1, 2]
    atom_2 = 0
    test_structure_1 = struc.Structure(cell, species_2, positions_1)
    test_structure_2 = struc.Structure(cell, species_2, positions_2)
    test_structure_3 = struc.Structure(cell, species_2, positions_3)

    env2_1 = env.AtomicEnvironment(test_structure_1, atom_2, cutoffs)
    env2_2 = env.AtomicEnvironment(test_structure_2, atom_2, cutoffs)
    env2_3 = env.AtomicEnvironment(test_structure_3, atom_2, cutoffs)

    # set hyperparameters
    sig1 = random()
    ls1 = random()
    sig2 = random()
    ls2 = random()
    d1 = 1
    d2 = 2

    hyps = np.array([sig1, ls1, sig2, ls2])

    # check force kernel
    calc1 = en.two_plus_three_en(env1_2, env2_2, hyps, cutoffs)
    calc2 = en.two_plus_three_en(env1_3, env2_3, hyps, cutoffs)
    calc3 = en.two_plus_three_en(env1_2, env2_3, hyps, cutoffs)
    calc4 = en.two_plus_three_en(env1_3, env2_2, hyps, cutoffs)

    kern_finite_diff = (calc1 + calc2 - calc3 - calc4) / (4*delt**2)
    kern_analytical = en.two_plus_three_body(env1_1, env2_1,
                                             d1, d2, hyps, cutoffs)

    tol = 1e-4
    assert(np.isclose(kern_finite_diff, kern_analytical, atol=tol))
Ejemplo n.º 27
0
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')
Ejemplo n.º 28
0
def test_two_plus_three_body_grad():
    # create env 1
    cell = np.eye(3)
    cutoffs = np.array([1, 1])

    positions_1 = [np.array([0., 0., 0.]),
                   np.array([random(), random(), random()]),
                   np.array([random(), random(), random()])]

    species_1 = [1, 2, 1]
    atom_1 = 0
    test_structure_1 = struc.Structure(cell, species_1, positions_1)
    env1 = env.AtomicEnvironment(test_structure_1, atom_1, cutoffs)

    # create env 2
    positions_1 = [np.array([0., 0., 0.]),
                   np.array([random(), random(), random()]),
                   np.array([random(), random(), random()])]

    species_2 = [1, 1, 2]
    atom_2 = 0
    test_structure_1 = struc.Structure(cell, species_2, positions_1)
    env2 = env.AtomicEnvironment(test_structure_1, atom_2, cutoffs)

    # set hyperparameters
    sig1 = random()
    ls1 = random()
    sig2 = random()
    ls2 = random()

    d1 = randint(1, 3)
    d2 = randint(1, 3)

    delta = 1e-8

    hyps = np.array([sig1, ls1, sig2, ls2])
    hyps1 = np.array([sig1+delta, ls1, sig2, ls2])
    hyps2 = np.array([sig1, ls1+delta, sig2, ls2])
    hyps3 = np.array([sig1, ls1, sig2+delta, ls2])
    hyps4 = np.array([sig1, ls1, sig2, ls2+delta])

    grad_test = en.two_plus_three_body_grad(env1, env2, d1, d2, hyps, cutoffs)

    sig1_derv_brute = (en.two_plus_three_body(env1, env2, d1, d2,
                                              hyps1, cutoffs) -
                       en.two_plus_three_body(env1, env2, d1, d2,
                                              hyps, cutoffs)) / delta

    l1_derv_brute = \
        (en.two_plus_three_body(env1, env2, d1, d2, hyps2, cutoffs) -
         en.two_plus_three_body(env1, env2, d1, d2, hyps, cutoffs)) / delta

    sig2_derv_brute = \
        (en.two_plus_three_body(env1, env2, d1, d2,
                                hyps3, cutoffs) -
         en.two_plus_three_body(env1, env2, d1, d2,
                                hyps, cutoffs)) / delta

    l2_derv_brute = \
        (en.two_plus_three_body(env1, env2, d1, d2, hyps4, cutoffs) -
         en.two_plus_three_body(env1, env2, d1, d2, hyps, cutoffs)) / delta

    tol = 1e-4
    assert(np.isclose(grad_test[1][0], sig1_derv_brute, atol=tol))
    assert(np.isclose(grad_test[1][1], l1_derv_brute, atol=tol))
    assert(np.isclose(grad_test[1][2], sig2_derv_brute, atol=tol))
    assert(np.isclose(grad_test[1][3], l2_derv_brute, atol=tol))
Ejemplo n.º 29
0
def test_two_plus_three_body_force_en():
    """Check that the analytical force/en kernel matches finite difference of
    energy kernel."""

    # create env 1
    delt = 1e-8
    cell = np.eye(3)
    cutoffs = np.array([1, 1])

    positions_1 = [np.array([0., 0., 0.]),
                   np.array([random(), random(), random()]),
                   np.array([random(), random(), random()]),
                   np.array([random(), random(), random()]),
                   np.array([random(), random(), random()]),
                   np.array([random(), random(), random()]),
                   np.array([random(), random(), random()]),
                   np.array([random(), random(), random()]),
                   np.array([random(), random(), random()])]
    positions_2 = deepcopy(positions_1)
    positions_2[0][0] = delt

    species_1 = [1, 2, 1]
    atom_1 = 0
    test_structure_1 = struc.Structure(cell, species_1, positions_1)
    test_structure_2 = struc.Structure(cell, species_1, positions_2)

    env1_1 = env.AtomicEnvironment(test_structure_1, atom_1, cutoffs)
    env1_2 = env.AtomicEnvironment(test_structure_2, atom_1, cutoffs)

    # create env 2
    positions_1 = [np.array([0., 0., 0.]),
                   np.array([random(), random(), random()]),
                   np.array([random(), random(), random()]),
                   np.array([random(), random(), random()]),
                   np.array([random(), random(), random()]),
                   np.array([random(), random(), random()]),
                   np.array([random(), random(), random()]),
                   np.array([random(), random(), random()]),
                   np.array([random(), random(), random()])]

    species_2 = [1, 1, 2]
    atom_2 = 0
    test_structure_1 = struc.Structure(cell, species_2, positions_1)
    env2 = env.AtomicEnvironment(test_structure_1, atom_2, cutoffs)

    # set hyperparameters
    sig1 = random()
    ls1 = random()
    sig2 = random()
    ls2 = random()
    d1 = 1

    hyps = np.array([sig1, ls1, sig2, ls2])

    # check force kernel
    calc1 = en.two_body_en(env1_2, env2, hyps[0:2], cutoffs)
    calc2 = en.two_body_en(env1_1, env2, hyps[0:2], cutoffs)
    calc3 = en.three_body_en(env1_2, env2, hyps[2:4], cutoffs)
    calc4 = en.three_body_en(env1_1, env2, hyps[2:4], cutoffs)

    kern_finite_diff = (calc1 - calc2) / (2 * delt) + \
        (calc3 - calc4) / (3 * delt)
    kern_analytical = \
        en.two_plus_three_force_en(env1_1, env2, d1, hyps, cutoffs)

    tol = 1e-4
    assert(np.isclose(-kern_finite_diff, kern_analytical, atol=tol))
Ejemplo n.º 30
0
store_predictions = []
store_mffpred = []
store_forces = []
var_err = 0
for n, snap in enumerate(test_snaps):
    structure = test_strucs[n]
    forces = test_forces[n]
    noa = len(structure.positions)

    predictions = np.zeros([noa, 3])
    variances = np.zeros([noa, 3])
    mff_pred = np.zeros([noa, 3])
    mff_var = np.zeros([noa, 3])

    for atom in range(noa):
        env_curr = env.AtomicEnvironment(structure, atom, cutoffs)

        for m in range(3):
            d = m + 1
            comp_pred, comp_var = gp_model.predict(env_curr, d)
            predictions[atom, m] = comp_pred
            variances[atom, m] = comp_var

        # make prediction with mff
        mff_f, mff_v = mff_model.predict(env_curr, mean_only=False)
        mff_pred[atom, :] = mff_f
        mff_var[atom, :] = mff_v
        var_err += np.mean(np.absolute(mff_v - variances[atom, :]))
#        print(env_curr.ctype, mff_v, variances[atom])

    store_predictions.append(predictions)