Beispiel #1
0
def strucs():
    """Create two random structures."""

    np.random.seed(0)
    positions_1 = np.random.rand(n_atoms, 3)
    positions_2 = np.random.rand(n_atoms, 3)
    structure_1 = struc.Structure(cell, species, positions_1)
    structure_2 = struc.Structure(cell, species, positions_2)
    strucs = [structure_1, structure_2]

    yield strucs
Beispiel #2
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
Beispiel #3
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))
Beispiel #4
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))
Beispiel #5
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
Beispiel #6
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
Beispiel #7
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]
Beispiel #8
0
    def get_structure_from_input(self, prev_pos_init):
        positions, species, cell, masses = \
            self.dft_module.parse_dft_input(self.dft_input)

        self.structure = struc.Structure(
            cell=cell, species=species, positions=positions, mass_dict=masses,
            prev_positions=prev_pos_init, species_labels=species)
Beispiel #9
0
    def output_md_structures(self):
        """
        Returns structure objects corresponding to the MD frames of an OTF run.
        :return:
        """

        structures = []
        cell = self.header["cell"]
        species = self.header["species"]
        for i in range(len(self.position_list)):
            if not self.calculate_energy:
                energy = 0
            else:
                energy = self.energies[i]

            cur_struc = struc.Structure(
                cell=cell,
                species=species,
                positions=self.position_list[i],
                forces=self.force_list[i],
                stds=self.uncertainty_list[i],
            )
            cur_struc.energy = energy
            # cur_struc.stress = self.stress_list[i]
            structures.append(cur_struc)
        return structures
Beispiel #10
0
    def make_gp(self,
                cell=None,
                kernel=None,
                kernel_grad=None,
                algo=None,
                call_no=None,
                cutoffs=None,
                hyps=None,
                init_gp=None,
                energy_force_kernel=None,
                hyp_no=None,
                par=True):

        if init_gp is None:
            # Use run's values as extracted from header
            # TODO Allow for kernel gradient in header
            if cell is None:
                cell = self.header['cell']
            if kernel is None:
                kernel = self.header['kernel']
            if kernel_grad is None:
                raise Exception('Kernel gradient not supplied')
            if algo is None:
                algo = self.header['algo']
            if cutoffs is None:
                cutoffs = self.header['cutoffs']
            if call_no is None:
                call_no = len(self.gp_position_list)
            if hyp_no is None:
                hyp_no = call_no
            if hyps is None:
                gp_hyps = self.gp_hyp_list[hyp_no - 1][-1]
            else:
                gp_hyps = hyps

            gp_model = \
                gp.GaussianProcess(kernel, kernel_grad, gp_hyps,
                                   cutoffs, opt_algorithm=algo,
                                   energy_force_kernel=energy_force_kernel,
                                   par=par)
        else:
            gp_model = init_gp
            call_no = len(self.gp_position_list)
            gp_hyps = self.gp_hyp_list[hyp_no - 1][-1]
            gp_model.hyps = gp_hyps

        for (positions, forces, atoms, _, species) in \
            zip(self.gp_position_list[:call_no],
                self.gp_force_list[:call_no],
                self.gp_atom_list[:call_no], self.gp_hyp_list[:call_no],
                self.gp_species_list[:call_no]):

            struc_curr = struc.Structure(cell, species, positions)

            gp_model.update_db(struc_curr, forces, custom_range=atoms)

        gp_model.set_L_alpha()

        return gp_model
Beispiel #11
0
def structure(otf_object):
    # create test structure
    otf_cell = otf_object.header['cell']
    species = np.array([47, 53] * 27)
    positions = otf_object.position_list[-1]
    test_struc = struc.Structure(otf_cell, species, positions)

    yield test_struc
    del test_struc
Beispiel #12
0
def dft_input_to_structure(qe_input: str):
    """
    Parses a qe input and returns the atoms in the file as a Structure object
    :param qe_input: QE Input file to parse
    :return:
    """
    positions, species, cell, masses = parse_dft_input(qe_input)
    _, coded_species = struc.get_unique_species(species)
    return struc.Structure(positions=positions, species=coded_species,
                           cell=cell, mass_dict=masses, species_labels=species)
Beispiel #13
0
    def make_gp(
        self,
        cell=None,
        call_no=None,
        hyps=None,
        init_gp=None,
        hyp_no=None,
        **kwargs,
    ):

        if "restart" in self.header and self.header["restart"] > 0:
            assert (
                init_gp is not None
            ), "Please input the init_gp as the gp model dumppedbefore restarting otf."

        if call_no is None:
            call_no = len(self.gp_position_list)
        if hyp_no is None:
            hyp_no = len(self.gp_hyp_list)  # use the last hyps by default
        if hyps is None:
            # check out the last non-empty element from the list
            hyps = self.gp_hyp_list[hyp_no - 1]
        if cell is None:
            cell = self.header["cell"]

        if init_gp is None:
            # Use run's values as extracted from header
            # TODO Allow for kernel gradient in header

            dictionary = deepcopy(self.header)
            dictionary["hyps"] = hyps
            for k in kwargs:
                if kwargs[k] is not None:
                    dictionary[k] = kwargs[k]

            gp_model = GaussianProcess.from_dict(dictionary)
        else:
            gp_model = init_gp
            gp_model.hyps = hyps

        for (positions, forces, atoms, species) in zip(
                self.gp_position_list[:call_no],
                self.gp_force_list[:call_no],
                self.gp_atom_list[:call_no],
                self.gp_species_list[:call_no],
        ):

            struc_curr = struc.Structure(cell, species, positions)

            gp_model.update_db(struc_curr, forces, custom_range=atoms)

        gp_model.set_L_alpha()

        return gp_model
Beispiel #14
0
    def make_gp(self, cell=None, kernel_name=None, algo=None,
                call_no=None, cutoffs=None, hyps=None, init_gp=None,
                hyp_no=None, par=True, kernel=None):

        if init_gp is None:
            # Use run's values as extracted from header
            # TODO Allow for kernel gradient in header
            if cell is None:
                cell = self.header['cell']
            if kernel_name is None:
                kernel_name = self.header['kernel_name']
            if algo is None:
                algo = self.header['algo']
            if cutoffs is None:
                cutoffs = self.header['cutoffs']
            if call_no is None:
                call_no = len(self.gp_position_list)
            if hyp_no is None:
                hyp_no = call_no
            if hyps is None:
                gp_hyps = self.gp_hyp_list[hyp_no-1][-1]
            else:
                gp_hyps = hyps

            if (kernel is not None) and (kernel_name is None):
                DeprecationWarning("kernel replaced with kernel_name")
                kernel_name = kernel.__name__

            gp_model = \
                gp.GaussianProcess(kernel_name=kernel_name,
                                   hyps=gp_hyps,
                                   cutoffs=cutoffs, opt_algorithm=algo,
                                   par=par)
        else:
            gp_model = init_gp
            call_no = len(self.gp_position_list)
            gp_hyps = self.gp_hyp_list[hyp_no-1][-1]
            gp_model.hyps = gp_hyps

        for (positions, forces, atoms, _, species) in \
            zip(self.gp_position_list[:call_no],
                self.gp_force_list[:call_no],
                self.gp_atom_list[:call_no], self.gp_hyp_list[:call_no],
                self.gp_species_list[:call_no]):

            struc_curr = struc.Structure(cell, species, positions)

            gp_model.update_db(struc_curr, forces, custom_range=atoms)

        gp_model.set_L_alpha()

        return gp_model
Beispiel #15
0
    def make_gp(
        self,
        cell=None,
        call_no=None,
        hyps=None,
        init_gp=None,
        hyp_no=None,
        **kwargs,
    ):

        if call_no is None:
            call_no = len(self.gp_position_list)
        if hyp_no is None:
            hyp_no = call_no
        if hyps is None:
            # check out the last non-empty element from the list
            for icall in reversed(range(hyp_no)):
                if len(self.gp_hyp_list[icall]) > 0:
                    hyps = self.gp_hyp_list[icall][-1]
                    break
        if cell is None:
            cell = self.header['cell']

        if init_gp is None:
            # Use run's values as extracted from header
            # TODO Allow for kernel gradient in header

            dictionary = deepcopy(self.header)
            dictionary['hyps'] = hyps
            for k in kwargs:
                if kwargs[k] is not None:
                    dictionary[k] = kwargs[k]

            gp_model = \
                GaussianProcess.from_dict(dictionary)
        else:
            gp_model = init_gp
            gp_model.hyps = hyps

        for (positions, forces, atoms, _, species) in \
            zip(self.gp_position_list[:call_no],
                self.gp_force_list[:call_no],
                self.gp_atom_list[:call_no], self.gp_hyp_list[:call_no],
                self.gp_species_list[:call_no]):

            struc_curr = struc.Structure(cell, species, positions)

            gp_model.update_db(struc_curr, forces, custom_range=atoms)

        gp_model.set_L_alpha()

        return gp_model
Beispiel #16
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
Beispiel #17
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
Beispiel #18
0
    def fit(self, parent_data):
        for image in parent_data:
            train_structure = struc.Structure(image.get_cell(),
                                              image.get_atomic_numbers(),
                                              image.get_positions())

            forces = image.get_forces(apply_constraint=False)
            energy = image.get_potential_energy(apply_constraint=False)

            self.gp_model.update_db(train_structure,
                                    forces, [],
                                    energy,
                                    mode="all",
                                    update_qr=True)
Beispiel #19
0
 def partial_fit(self, new_dataset):
     for image in new_dataset:
         train_structure = struc.Structure(image.get_cell(),
                                           image.get_atomic_numbers(),
                                           image.get_positions())
         forces = image.get_forces(apply_constraint=False)
         energy = image.get_potential_energy(apply_constraint=False)
         self.gp_model.update_db(
             train_structure,
             forces,
             self.update_gp_range,
             energy,
             mode=self.update_gp_mode,
             update_qr=True,
         )
Beispiel #20
0
    def output_md_structures(self):
        """
        Returns structure objects corresponding to the MD frames of an OTF run.
        :return:
        """

        positions = self.position_list
        structures = []
        cell = self.header['cell']
        species = self.header['species']
        forces = self.force_list
        stds = self.uncertainty_list
        for i in range(len(positions)):
            cur_struc = struc.Structure(cell=cell, species=species,
                                        positions=positions[i])
            cur_struc.forces = forces[i]
            cur_struc.stds = stds[i]
            structures.append(cur_struc)
        return structures
Beispiel #21
0
    def build_bond_struc(self, struc_params):
        '''
        build a bond structure, used in grid generating
        '''

        cutoff = np.min(self.GP.cutoffs)
        cell = struc_params['cube_lat']
        mass_dict = struc_params['mass_dict']
        bond_struc = []
        for bodies in [2, 3]:
            species = [struc_params['species'] for i in range(bodies)]
            positions = [[(i+1)/(bodies+1)*cutoff, 0, 0] \
                        for i in range(bodies)]
            bond_struc.append(
                struc.Structure(cell, species, positions, mass_dict))
        if self.bodies == '2':
            return bond_struc[0]
        elif self.bodies == '3':
            return bond_struc[1]
        elif self.bodies == '2+3':
            return bond_struc
Beispiel #22
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
Beispiel #23
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
Beispiel #24
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
        N_Ag += 1
    else:
        N_Pd += 1
species = ['Ag'] * N_Ag + ['Pd'] * N_Pd
nat = len(species)
dump.close()

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))
Beispiel #26
0
    def __init__(self,
                 dft_input: str,
                 dt: float,
                 number_of_steps: int,
                 gp: gp.GaussianProcess,
                 dft_loc: str,
                 std_tolerance_factor: float = 1,
                 prev_pos_init: np.ndarray = None,
                 par: bool = False,
                 skip: int = 0,
                 init_atoms: List[int] = None,
                 calculate_energy=False,
                 output_name='otf_run',
                 max_atoms_added=1,
                 freeze_hyps=10,
                 rescale_steps=[],
                 rescale_temps=[],
                 dft_softwarename="qe",
                 no_cpus=1,
                 npool=None,
                 mpi="srun"):

        self.dft_input = dft_input
        self.dt = dt
        self.number_of_steps = number_of_steps
        self.gp = gp
        self.dft_loc = dft_loc
        self.std_tolerance = std_tolerance_factor
        self.skip = skip
        self.dft_step = True
        self.freeze_hyps = freeze_hyps
        self.dft_module = dft_software[dft_softwarename]

        # parse input file
        positions, species, cell, masses = \
            self.dft_module.parse_dft_input(self.dft_input)

        _, coded_species = struc.get_unique_species(species)

        self.structure = struc.Structure(cell=cell,
                                         species=coded_species,
                                         positions=positions,
                                         mass_dict=masses,
                                         prev_positions=prev_pos_init,
                                         species_labels=species)

        self.noa = self.structure.positions.shape[0]
        self.atom_list = list(range(self.noa))
        self.curr_step = 0

        self.max_atoms_added = max_atoms_added

        # initialize local energies
        if calculate_energy:
            self.local_energies = np.zeros(self.noa)
        else:
            self.local_energies = None

        # set atom list for initial dft run
        if init_atoms is None:
            self.init_atoms = [int(n) for n in range(self.noa)]
        else:
            self.init_atoms = init_atoms

        self.dft_count = 0

        # set pred function
        if not par and not calculate_energy:
            self.pred_func = predict.predict_on_structure
        elif par and not calculate_energy:
            self.pred_func = predict.predict_on_structure_par
        elif not par and calculate_energy:
            self.pred_func = predict.predict_on_structure_en
        elif par and calculate_energy:
            self.pred_func = predict.predict_on_structure_par_en
        self.par = par

        # set rescale attributes
        self.rescale_steps = rescale_steps
        self.rescale_temps = rescale_temps

        self.output = Output(output_name, always_flush=True)

        # set number of cpus and npool for qe runs
        self.no_cpus = no_cpus
        self.npool = npool
        self.mpi = mpi
Beispiel #27
0
    def build_bond_struc(self, struc_params):

        '''
        build a bond structure, used in grid generating
        '''

        cutoff = np.min(self.cutoffs)
        cell = struc_params['cube_lat']
        species_list = struc_params['species']
        N_spc = len(species_list)

        # ------------------- 2 body (2 atoms (1 bond) config) ---------------
        bond_struc_2 = []
        spc_2 = []
        if 2 in self.bodies:
            bodies = 2
            for spc1_ind, spc1 in enumerate(species_list):
                for spc2 in species_list[spc1_ind:]:
                    species = [spc1, spc2]
                    spc_2.append(species)
                    positions = [[(i+1)/(bodies+1)*cutoff, 0, 0]
                                 for i in range(bodies)]
                    spc_struc = \
                        struc.Structure(cell, species, positions)
                    spc_struc.coded_species = np.array(species)
                    bond_struc_2.append(spc_struc)

        # ------------------- 3 body (3 atoms (1 triplet) config) -------------
        bond_struc_3 = []
        spc_3 = []
        if 3 in self.bodies:
            bodies = 3
            for spc1_ind in range(N_spc):
                spc1 = species_list[spc1_ind]
                for spc2_ind in range(N_spc):  # (spc1_ind, N_spc):
                    spc2 = species_list[spc2_ind]
                    for spc3_ind in range(N_spc):  # (spc2_ind, N_spc):
                        spc3 = species_list[spc3_ind]
                        species = [spc1, spc2, spc3]
                        spc_3.append(species)
                        positions = [[(i+1)/(bodies+1)*cutoff, 0, 0]
                                     for i in range(bodies)]
                        spc_struc = struc.Structure(cell, species, positions)
                        spc_struc.coded_species = np.array(species)
                        bond_struc_3.append(spc_struc)

#                    if spc1 != spc2:
#                        species = [spc2, spc3, spc1]
#                        spc_3.append(species)
#                        positions = [[(i+1)/(bodies+1)*cutoff, 0, 0] \
#                                    for i in range(bodies)]
#                        spc_struc = struc.Structure(cell, species, positions)
#                        spc_struc.coded_species = np.array(species)
#                        bond_struc_3.append(spc_struc)
#                    if spc2 != spc3:
#                        species = [spc3, spc1, spc2]
#                        spc_3.append(species)
#                        positions = [[(i+1)/(bodies+1)*cutoff, 0, 0] \
#                                    for i in range(bodies)]
#                        spc_struc = struc.Structure(cell, species, positions)
#                        spc_struc.coded_species = np.array(species)
#                        bond_struc_3.append(spc_struc)

        self.bond_struc = [bond_struc_2, bond_struc_3]
        self.spcs = [spc_2, spc_3]
Beispiel #28
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))
Beispiel #29
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))
Beispiel #30
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))