Ejemplo n.º 1
0
def test_fp_match():
    for i in range(100):
        # Tests whether the generated fingerprints are consistent with that of AMPs
        atoms = molecule("H2O")
        atoms.set_cell([10, 10, 10])
        atoms.set_pbc = [True] * 3

        atoms.set_calculator(
            sp(atoms=atoms, energy=-1, forces=np.array([[-1, -1, -1], [-1, -1, -1]]))
        )

        Gs = {}
        images = [atoms]
        Gs["G2_etas"] = [0.005] * 2
        Gs["G2_rs_s"] = [0] * 2
        Gs["G4_etas"] = [0.005] * 2
        Gs["G4_zetas"] = [1.0, 4.0]
        Gs["G4_gammas"] = [1.0, -1.0]
        Gs["cutoff"] = 6.5

        elements = list(
            sorted(set([atom.symbol for atoms in images for atom in atoms]))
        )
        G = make_symmetry_functions(elements=elements, type="G2", etas=Gs["G2_etas"])
        G += make_symmetry_functions(
            elements=elements,
            type="G4",
            etas=Gs["G4_etas"],
            zetas=Gs["G4_zetas"],
            gammas=Gs["G4_gammas"],
        )
        G = {"O": G, "H": G}

        hashes = stock_hash(images)
        amp_hash = list(hashes.keys())[0]

        make_amp_descriptors_simple_nn(images, Gs, cores=1, label='test', elements=elements)
        s_nn_hash = list(new_hash(images, Gs).keys())[0]

        with open("amp-data-fingerprints.ampdb/loose/" + s_nn_hash, "rb") as f:
            simple_nn = load(f)
        os.system("rm amp-data-fingerprints.ampdb/loose/" + s_nn_hash)

        descriptor = Gaussian(elements=elements, Gs=G, cutoff=Cosine(Gs["cutoff"]))
        descriptor.calculate_fingerprints(hashes, calculate_derivatives=True)
        with open("amp-data-fingerprints.ampdb/loose/" + amp_hash, "rb") as f:
            amp = load(f)
        os.system("rm amp-data-fingerprints.ampdb/loose/" + amp_hash)

        for s, am in zip(simple_nn, amp):
            for i, j in zip(s[1], am[1]):
                assert abs(i - j) <= 1e-5, "Fingerprints do not match!"
Ejemplo n.º 2
0
def test():
    """Gaussian fingerprints consistency.

    Tests that pure-python and fortran, plus different number of cores
    give same results.
    """

    images = make_images()
    images = hash_images(images, ordered=True)

    ref_fps = {}
    ref_fp_primes = {}
    count = 0
    for fortran in [False, True]:
        for cores in range(1, 2):
            descriptor = Gaussian(fortran=fortran,
                                  dblabel='Gaussian-%s-%d' % (fortran, cores))
            descriptor.calculate_fingerprints(images,
                                              parallel={'cores': cores},
                                              log=None,
                                              calculate_derivatives=True)
            for hash, image in images.items():
                if count == 0:
                    ref_fps[hash] = descriptor.fingerprints[hash]
                    ref_fp_primes[hash] = descriptor.fingerprintprimes[hash]
                else:
                    fps = descriptor.fingerprints[hash]
                    # Checking consistency between fingerprints
                    for (element1, afp1), \
                            (element2, afp2) in zip(ref_fps[hash], fps):
                        assert element1 == element2, \
                            'fortran-python consistency for Gaussian '
                        'fingerprints broken!'
                        for _, __ in zip(afp1, afp2):
                            assert (abs(_ - __) < 10 ** (-15.)), \
                                'fortran-python consistency for Gaussian '
                            'fingerprints broken!'
                    # Checking consistency between fingerprint primes
                    fpprime = descriptor.fingerprintprimes[hash]
                    for key, value in ref_fp_primes[hash].items():
                        for _, __ in zip(value, fpprime[key]):
                            assert (abs(_ - __) < 10 ** (-15.)), \
                                'fortran-python consistency for Gaussian '
                            'fingerprint primes broken!'
            count += 1
def test_fp_match():
    slab = fcc100("Cu", size=(3, 3, 3))
    ads = molecule("CO")
    add_adsorbate(slab, ads, 4, offset=(1, 1))
    cons = FixAtoms(indices=[
        atom.index for atom in slab if (atom.tag == 2 or atom.tag == 3)
    ])
    slab.set_constraint(cons)
    slab.center(vacuum=13.0, axis=2)
    slab.set_pbc(True)
    slab.wrap(pbc=[True] * 3)
    slab.set_calculator(EMT())

    images = [slab]

    Gs = {}
    Gs["G2_etas"] = [2]
    Gs["G2_rs_s"] = [0]
    Gs["G4_etas"] = [0.005]
    Gs["G4_zetas"] = [1.0]
    Gs["G4_gammas"] = [1.0]
    Gs["cutoff"] = 6.5

    elements = np.array([atom.symbol for atoms in images for atom in atoms])
    _, idx = np.unique(elements, return_index=True)
    elements = list(elements[np.sort(idx)])

    G = make_symmetry_functions(elements=elements,
                                type="G2",
                                etas=Gs["G2_etas"])
    G += make_symmetry_functions(
        elements=elements,
        type="G4",
        etas=Gs["G4_etas"],
        zetas=Gs["G4_zetas"],
        gammas=Gs["G4_gammas"],
    )
    G = {"O": G, "C": G, "Cu": G}

    hashes = stock_hash(images)
    snn_hashes = new_hash(images, Gs=Gs)
    AtomsDataset(images,
                 SNN_Gaussian,
                 Gs,
                 forcetraining=True,
                 label="test",
                 cores=10)

    descriptor = Gaussian(elements=elements,
                          Gs=G,
                          cutoff=Gs["cutoff"],
                          dblabel='amp')
    descriptor.calculate_fingerprints(hashes, calculate_derivatives=True)

    for idx in range(len(images)):
        amp_hash = list(hashes.keys())[idx]
        s_nn_hash = list(snn_hashes.keys())[idx]
        # SimpleNN
        with open("amp-data-fingerprints.ampdb/loose/" + s_nn_hash, "rb") as f:
            simple_nn = load(f)
        os.system("rm amp-data-fingerprints.ampdb/loose/" + s_nn_hash)

        with open("amp-data-fingerprint-primes.ampdb/loose/" + s_nn_hash,
                  "rb") as f:
            simple_nn_prime = load(f)
        os.system("rm amp-data-fingerprint-primes.ampdb/loose/" + s_nn_hash)

        # AMP
        with open("amp-fingerprints.ampdb/loose/" + amp_hash, "rb") as f:
            amp = load(f)
        os.system("rm amp-fingerprints.ampdb/loose/" + amp_hash)

        with open("amp-fingerprint-primes.ampdb/loose/" + amp_hash, "rb") as f:
            amp_prime = load(f)
        os.system("rm amp-fingerprint-primes.ampdb/loose/" + amp_hash)

        key = amp_prime.keys()

        for s, am in zip(simple_nn, amp):
            for i, j in zip(s[1], am[1]):
                assert abs(i -
                           j) <= 1e-4, "Fingerprints do not match! %s, %s" % (
                               i, j)
        for idx in key:
            for s, am in zip(simple_nn_prime[idx], amp_prime[idx]):
                assert abs(s - am) <= 1e-4, "Fingerprint primes do not match!"
def test_calcs():
    """Gaussian/Neural non-periodic standard.

    Checks that the answer matches that expected from previous Mathematica
    calculations.
    """

    #: Making the list of non-periodic images
    images = [
        Atoms(
            symbols="PdOPd2",
            pbc=np.array([False, False, False], dtype=bool),
            calculator=EMT(),
            cell=np.array([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]),
            positions=np.array([[0.0, 0.0, 0.0], [0.0, 2.0, 0.0],
                                [0.0, 0.0, 3.0], [1.0, 0.0, 0.0]]),
        ),
        Atoms(
            symbols="PdOPd2",
            pbc=np.array([False, False, False], dtype=bool),
            calculator=EMT(),
            cell=np.array([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]),
            positions=np.array([[0.0, 1.0, 0.0], [1.0, 2.0, 1.0],
                                [-1.0, 1.0, 2.0], [1.0, 3.0, 2.0]]),
        ),
        Atoms(
            symbols="PdO",
            pbc=np.array([False, False, False], dtype=bool),
            calculator=EMT(),
            cell=np.array([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]),
            positions=np.array([[2.0, 1.0, -1.0], [1.0, 2.0, 1.0]]),
        ),
        Atoms(
            symbols="Pd2O",
            pbc=np.array([False, False, False], dtype=bool),
            calculator=EMT(),
            cell=np.array([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]),
            positions=np.array([[-2.0, -1.0, -1.0], [1.0, 2.0, 1.0],
                                [3.0, 4.0, 4.0]]),
        ),
        Atoms(
            symbols="Cu",
            pbc=np.array([False, False, False], dtype=bool),
            calculator=EMT(),
            cell=np.array([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]),
            positions=np.array([[0.0, 0.0, 0.0]]),
        ),
    ]

    [a.get_potential_energy() for a in images]
    # Parameters
    hiddenlayers = {"O": (2, ), "Pd": (2, ), "Cu": (2, )}

    Gs = {}
    Gs["G2_etas"] = [0.2]
    Gs["G2_rs_s"] = [0]
    Gs["G4_etas"] = [0.4]
    Gs["G4_zetas"] = [1]
    Gs["G4_gammas"] = [1]
    Gs["cutoff"] = 6.5

    elements = ["O", "Pd", "Cu"]

    G = make_symmetry_functions(elements=elements,
                                type="G2",
                                etas=Gs["G2_etas"])
    G += make_symmetry_functions(
        elements=elements,
        type="G4",
        etas=Gs["G4_etas"],
        zetas=Gs["G4_zetas"],
        gammas=Gs["G4_gammas"],
    )
    hashed_images = hash_images(images, Gs)
    descriptor = Gaussian(Gs=G, cutoff=Gs["cutoff"])
    descriptor.calculate_fingerprints(hashed_images,
                                      calculate_derivatives=True)
    fingerprints_range = calculate_fingerprints_range(descriptor,
                                                      hashed_images)

    weights = OrderedDict([
        (
            "O",
            OrderedDict([
                (
                    1,
                    np.array([
                        [0.5, 0.5],
                        [0.5, 0.5],
                        [0.5, 0.5],
                        [0.5, 0.5],
                        [0.5, 0.5],
                        [0.5, 0.5],
                        [0.5, 0.5],
                        [0.5, 0.5],
                        [0.5, 0.5],
                        [0.5, 0.5],
                    ]),
                ),
                (2, np.matrix([[0.5], [0.5], [0.5]])),
            ]),
        ),
        (
            "Pd",
            OrderedDict([
                (
                    1,
                    np.array([
                        [0.5, 0.5],
                        [0.5, 0.5],
                        [0.5, 0.5],
                        [0.5, 0.5],
                        [0.5, 0.5],
                        [0.5, 0.5],
                        [0.5, 0.5],
                        [0.5, 0.5],
                        [0.5, 0.5],
                        [0.5, 0.5],
                    ]),
                ),
                (2, np.array([[0.5], [0.5], [0.5]])),
            ]),
        ),
        (
            "Cu",
            OrderedDict([
                (
                    1,
                    np.array([
                        [0.5, 0.5],
                        [0.5, 0.5],
                        [0.5, 0.5],
                        [0.5, 0.5],
                        [0.5, 0.5],
                        [0.5, 0.5],
                        [0.5, 0.5],
                        [0.5, 0.5],
                        [0.5, 0.5],
                        [0.5, 0.5],
                    ]),
                ),
                (2, np.array([[0.5], [0.5], [0.5]])),
            ]),
        ),
    ])

    scalings = OrderedDict([
        ("O", OrderedDict([("intercept", 0), ("slope", 1)])),
        ("Pd", OrderedDict([("intercept", 0), ("slope", 1)])),
        ("Cu", OrderedDict([("intercept", 0), ("slope", 1)])),
    ])

    calc = Amp(
        descriptor,
        model=NeuralNetwork(
            hiddenlayers=hiddenlayers,
            weights=weights,
            scalings=scalings,
            activation="linear",
            fprange=fingerprints_range,
            mode="atom-centered",
            fortran=False,
        ),
        logging=False,
    )

    amp_energies = [calc.get_potential_energy(image) for image in images]
    amp_forces = [calc.get_forces(image) for image in images]
    amp_forces = np.concatenate(amp_forces)

    device = "cpu"
    dataset = AtomsDataset(images,
                           descriptor=DummyGaussian,
                           cores=1,
                           label='test',
                           Gs=Gs,
                           forcetraining=True)
    fp_length = dataset.fp_length
    batch_size = len(dataset)
    dataloader = DataLoader(dataset,
                            batch_size,
                            collate_fn=collate_amp,
                            shuffle=False)
    model = FullNN(elements, [fp_length, 2, 2], device, forcetraining=True)
    for name, layer in model.named_modules():
        if isinstance(layer, Dense):
            layer.activation = None
            init.constant_(layer.weight, 0.5)
            init.constant_(layer.bias, 0.5)
    for batch in dataloader:
        input_data = [batch[0], len(batch[1]), batch[3]]
        for element in elements:
            input_data[0][element][0] = (
                input_data[0][element][0].to(device).requires_grad_(True))
        fp_primes = batch[4]
        energy_pred, force_pred = model(input_data, fp_primes)

    for idx, i in enumerate(amp_energies):
        assert round(i, 4) == round(
            energy_pred.tolist()[idx][0],
            4), "The predicted energy of image %i is wrong!" % (idx + 1)
    print("Energy predictions are correct!")
    for idx, sample in enumerate(amp_forces):
        for idx_d, value in enumerate(sample):
            predict = force_pred.tolist()[idx][idx_d]
            assert abs(value - predict) < 0.00001, (
                "The predicted force of image % i, direction % i is wrong! Values: %s vs %s"
                % (idx + 1, idx_d, value, force_pred.tolist()[idx][idx_d]))
    print("Force predictions are correct!")
Ejemplo n.º 5
0
def test_calcs():
    """Gaussian/Neural non-periodic standard.

    Checks that the answer matches that expected from previous Mathematica
    calculations.
    """

    #: Making the list of non-periodic images
    images = [
        Atoms(
            symbols="PdOPd2",
            pbc=np.array([False, False, False], dtype=bool),
            calculator=EMT(),
            cell=np.array([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]),
            positions=np.array([[0.0, 0.0, 0.0], [0.0, 2.0, 0.0],
                                [0.0, 0.0, 3.0], [1.0, 0.0, 0.0]]),
        ),
        Atoms(
            symbols="PdOPd2",
            pbc=np.array([False, False, False], dtype=bool),
            calculator=EMT(),
            cell=np.array([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]),
            positions=np.array([[0.0, 1.0, 0.0], [1.0, 2.0, 1.0],
                                [-1.0, 1.0, 2.0], [1.0, 3.0, 2.0]]),
        ),
        Atoms(
            symbols="PdO",
            pbc=np.array([False, False, False], dtype=bool),
            calculator=EMT(),
            cell=np.array([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]),
            positions=np.array([[2.0, 1.0, -1.0], [1.0, 2.0, 1.0]]),
        ),
        Atoms(
            symbols="Pd2O",
            pbc=np.array([False, False, False], dtype=bool),
            calculator=EMT(),
            cell=np.array([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]),
            positions=np.array([[-2.0, -1.0, -1.0], [1.0, 2.0, 1.0],
                                [3.0, 4.0, 4.0]]),
        ),
        Atoms(
            symbols="Cu",
            pbc=np.array([False, False, False], dtype=bool),
            calculator=EMT(),
            cell=np.array([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]),
            positions=np.array([[0.0, 0.0, 0.0]]),
        ),
    ]

    # Parameters
    hiddenlayers = {"O": (2, ), "Pd": (2, ), "Cu": (2, )}

    Gs = {}
    Gs["G2_etas"] = [0.2]
    Gs["G2_rs_s"] = [0]
    Gs["G4_etas"] = [0.4]
    Gs["G4_zetas"] = [1]
    Gs["G4_gammas"] = [1]
    Gs["cutoff"] = 6.5

    elements = ["O", "Pd", "Cu"]

    G = make_symmetry_functions(elements=elements,
                                type="G2",
                                etas=Gs["G2_etas"])
    G += make_symmetry_functions(
        elements=elements,
        type="G4",
        etas=Gs["G4_etas"],
        zetas=Gs["G4_zetas"],
        gammas=Gs["G4_gammas"],
    )
    amp_images = amp_hash(images)
    descriptor = Gaussian(Gs=G, cutoff=Gs["cutoff"])
    descriptor.calculate_fingerprints(amp_images, calculate_derivatives=True)
    fingerprints_range = calculate_fingerprints_range(descriptor, amp_images)
    np.random.seed(1)
    O_weights_1 = np.random.rand(10, 2)
    O_weights_2 = np.random.rand(1, 3).reshape(-1, 1)
    np.random.seed(2)
    Pd_weights_1 = np.random.rand(10, 2)
    Pd_weights_2 = np.random.rand(1, 3).reshape(-1, 1)
    np.random.seed(3)
    Cu_weights_1 = np.random.rand(10, 2)
    Cu_weights_2 = np.random.rand(1, 3).reshape(-1, 1)

    weights = OrderedDict([
        ("O", OrderedDict([(1, O_weights_1), (2, O_weights_2)])),
        ("Pd", OrderedDict([(1, Pd_weights_1), (2, Pd_weights_2)])),
        ("Cu", OrderedDict([(1, Cu_weights_1), (2, Cu_weights_2)])),
    ])

    scalings = OrderedDict([
        ("O", OrderedDict([("intercept", 0), ("slope", 1)])),
        ("Pd", OrderedDict([("intercept", 0), ("slope", 1)])),
        ("Cu", OrderedDict([("intercept", 0), ("slope", 1)])),
    ])

    calc = Amp(
        descriptor,
        model=NeuralNetwork(
            hiddenlayers=hiddenlayers,
            weights=weights,
            scalings=scalings,
            activation="tanh",
            fprange=fingerprints_range,
            mode="atom-centered",
            fortran=False,
        ),
        logging=False,
    )

    amp_energies = [calc.get_potential_energy(image) for image in images]
    amp_forces = [calc.get_forces(image) for image in images]
    amp_forces = np.concatenate(amp_forces)

    torch_O_weights_1 = torch.FloatTensor(O_weights_1[:-1, :]).t()
    torch_O_bias_1 = torch.FloatTensor(O_weights_1[-1, :])
    torch_O_weights_2 = torch.FloatTensor(O_weights_2[:-1, :]).t()
    torch_O_bias_2 = torch.FloatTensor(O_weights_2[-1, :])
    torch_Pd_weights_1 = torch.FloatTensor(Pd_weights_1[:-1, :]).t()
    torch_Pd_bias_1 = torch.FloatTensor(Pd_weights_1[-1, :])
    torch_Pd_weights_2 = torch.FloatTensor(Pd_weights_2[:-1, :]).t()
    torch_Pd_bias_2 = torch.FloatTensor(Pd_weights_2[-1, :])
    torch_Cu_weights_1 = torch.FloatTensor(Cu_weights_1[:-1, :]).t()
    torch_Cu_bias_1 = torch.FloatTensor(Cu_weights_1[-1, :])
    torch_Cu_weights_2 = torch.FloatTensor(Cu_weights_2[:-1, :]).t()
    torch_Cu_bias_2 = torch.FloatTensor(Cu_weights_2[-1, :])

    device = "cpu"
    dataset = AtomsDataset(
        images,
        descriptor=Gaussian,
        cores=1,
        label="consistency",
        Gs=Gs,
        forcetraining=True,
    )

    fp_length = dataset.fp_length
    batch_size = len(dataset)
    dataloader = DataLoader(dataset,
                            batch_size,
                            collate_fn=collate_amp,
                            shuffle=False)
    model = FullNN(elements, [fp_length, 2, 2], device, forcetraining=True)
    model.state_dict()["elementwise_models.O.model_net.0.weight"].copy_(
        torch_O_weights_1)
    model.state_dict()["elementwise_models.O.model_net.0.bias"].copy_(
        torch_O_bias_1)
    model.state_dict()["elementwise_models.O.model_net.2.weight"].copy_(
        torch_O_weights_2)
    model.state_dict()["elementwise_models.O.model_net.2.bias"].copy_(
        torch_O_bias_2)
    model.state_dict()["elementwise_models.Pd.model_net.0.weight"].copy_(
        torch_Pd_weights_1)
    model.state_dict()["elementwise_models.Pd.model_net.0.bias"].copy_(
        torch_Pd_bias_1)
    model.state_dict()["elementwise_models.Pd.model_net.2.weight"].copy_(
        torch_Pd_weights_2)
    model.state_dict()["elementwise_models.Pd.model_net.2.bias"].copy_(
        torch_Pd_bias_2)
    model.state_dict()["elementwise_models.Cu.model_net.0.weight"].copy_(
        torch_Cu_weights_1)
    model.state_dict()["elementwise_models.Cu.model_net.0.bias"].copy_(
        torch_Cu_bias_1)
    model.state_dict()["elementwise_models.Cu.model_net.2.weight"].copy_(
        torch_Cu_weights_2)
    model.state_dict()["elementwise_models.Cu.model_net.2.bias"].copy_(
        torch_Cu_bias_2)
    import torch.nn as nn
    for name, layer in model.named_modules():
        if isinstance(layer, MLP):
            layer.model_net = nn.Sequential(layer.model_net, Tanh())

    for batch in dataloader:
        x = to_tensor(batch[0], device)
        y = to_tensor(batch[1], device)
        energy_pred, force_pred = model(x)
    for idx, i in enumerate(amp_energies):
        assert round(i, 4) == round(
            energy_pred.tolist()[idx][0],
            4), "The predicted energy of image %i is wrong!" % (idx + 1)
    print("Energy predictions are correct!")
    for idx, sample in enumerate(amp_forces):
        for idx_d, value in enumerate(sample):
            predict = force_pred.tolist()[idx][idx_d]
            assert abs(value - predict) < 0.0001, (
                "The predicted force of image % i, direction % i is wrong! Values: %s vs %s"
                % (idx + 1, idx_d, value, force_pred.tolist()[idx][idx_d]))
    print("Force predictions are correct!")
Ejemplo n.º 6
0
    nn1_.rotate([0, 0, 1], ang1)

    nn2_ = nn2.copy()
    nn2_.rotate([0, 0, 1], ang2)
    nn2_.positions = nn2_.positions + np.array([3.0, 0.0, 0.0])

    for atom in nn2_:
        nn1_.append(atom)
    images.append(nn1_)

view(images)

# # Fingerprint using Amp.
descriptor = Gaussian()
images = hash_images(images, ordered=True)
descriptor.calculate_fingerprints(images)


def barplot(hash, name, title):
    """Makes a barplot of the fingerprint about the O atom."""
    fp = descriptor.fingerprints[hash][0]
    fig, ax = pyplot.subplots()
    ax.bar(range(len(fp[1])), fp[1])
    ax.set_title(title)
    ax.set_ylim(0., 2.)
    ax.set_xlabel('fingerprint')
    ax.set_ylabel('value')
    fig.savefig(name)


for index, hash in enumerate(images.keys()):