Beispiel #1
0
    def test_dsygv_dgelsd(self):
        a = Diamond('C', size=[4,4,4])
        b = a.copy()
        b.positions += (np.random.random(b.positions.shape)-0.5)*0.1
        i, j = neighbour_list("ij", b, 1.85)

        dr_now = mic(b.positions[i] - b.positions[j], b.cell)
        dr_old = mic(a.positions[i] - a.positions[j], a.cell)

        dgrad1 = get_delta_plus_epsilon_dgesv(len(b), i, dr_now, dr_old)
        dgrad2 = get_delta_plus_epsilon(len(b), i, dr_now, dr_old)

        self.assertArrayAlmostEqual(dgrad1, dgrad2)
Beispiel #2
0
def get_D_square_min(atoms_now,
                     atoms_old,
                     i_now,
                     j_now,
                     delta_plus_epsilon=None):
    """
    Calculate the D^2_min norm of Falk and Langer
    """
    nat = len(atoms_now)
    assert len(atoms_now) == len(atoms_old)

    pos_now = atoms_now.positions
    pos_old = atoms_old.positions

    # Compute current and old distance vectors. Note that current distance
    # vectors cannot be taken from the neighbor calculation, because neighbors
    # are calculated from the sheared cell while these distance need to come
    # from the unsheared cell. Taking the distance from the unsheared cell
    # make periodic boundary conditions (and flipping of cell) a lot easier.
    dr_now = mic(pos_now[i_now] - pos_now[j_now], atoms_now.cell)
    dr_old = mic(pos_old[i_now] - pos_old[j_now], atoms_old.cell)

    # Sanity check: Shape needs to be identical!
    assert dr_now.shape == dr_old.shape

    if delta_plus_epsilon is None:
        # Get minimum strain tensor
        delta_plus_epsilon = get_delta_plus_epsilon(nat, i_now, dr_now, dr_old)

    # Spread epsilon out for each neighbor index
    delta_plus_epsilon_n = delta_plus_epsilon[i_now]

    # Compute D^2_min (residual of the least squares fit)
    residual_n = np.sum((dr_now - np.sum(
        delta_plus_epsilon_n.reshape(-1, 3, 3) * dr_old.reshape(-1, 1, 3),
        axis=2))**2,
                        axis=1)

    # For each atom, sum over all neighbors
    residual = np.bincount(i_now, weights=residual_n)

    return delta_plus_epsilon, residual
Beispiel #3
0
 def _fill_shifts_upto(self, i):
     # Iterate up to frame i the full trajectory first and generate a list
     # of displacement vectors.
     while len(self.shifts) <= i:
         j = len(self.shifts)
         a0 = self.traj[j - 1]
         a1 = self.traj[j]
         s0 = a0.get_scaled_positions() % 1.0
         s1 = a1.get_scaled_positions() % 1.0
         sdisps = mic(s1 - s0, np.eye(3), pbc=a0.pbc)
         self.shifts += [self.shifts[-1] + sdisps.mean(axis=0)]
Beispiel #4
0
 def _fill_shifts_upto(self, i):
     # Iterate up to frame i the full trajectory first and generate a list
     # of displacement vectors.
     while len(self.shifts) <= i:
         j = len(self.shifts)
         a0 = self.traj[j-1]
         a1 = self.traj[j]
         s0 = a0.get_scaled_positions()%1.0
         s1 = a1.get_scaled_positions()%1.0
         sdisps = mic(s1-s0, np.eye(3), pbc=a0.pbc)
         self.shifts += [self.shifts[-1]+sdisps.mean(axis=0)]
Beispiel #5
0
def get_D_square_min(atoms_now, atoms_old, i_now, j_now, delta_plus_epsilon=None):
    """
    Calculate the D^2_min norm of Falk and Langer
    """
    nat = len(atoms_now)
    assert len(atoms_now) == len(atoms_old)

    pos_now = atoms_now.positions
    pos_old = atoms_old.positions

    # Compute current and old distance vectors. Note that current distance
    # vectors cannot be taken from the neighbor calculation, because neighbors
    # are calculated from the sheared cell while these distance need to come
    # from the unsheared cell. Taking the distance from the unsheared cell
    # make periodic boundary conditions (and flipping of cell) a lot easier.
    dr_now = mic(pos_now[i_now] - pos_now[j_now], atoms_now.cell)
    dr_old = mic(pos_old[i_now] - pos_old[j_now], atoms_old.cell)

    # Sanity check: Shape needs to be identical!
    assert dr_now.shape == dr_old.shape

    if delta_plus_epsilon is None:
        # Get minimum strain tensor
        delta_plus_epsilon = get_delta_plus_epsilon(nat, i_now, dr_now, dr_old)

    # Spread epsilon out for each neighbor index
    delta_plus_epsilon_n = delta_plus_epsilon[i_now]

    # Compute D^2_min (residual of the least squares fit)
    residual_n = np.sum(
        (
        dr_now-
        np.sum(delta_plus_epsilon_n.reshape(-1,3,3)*dr_old.reshape(-1,1,3),
               axis=2)
        )**2,
        axis=1)

    # For each atom, sum over all neighbors
    residual = np.bincount(i_now, weights=residual_n)

    return delta_plus_epsilon, residual
Beispiel #6
0
    def test_neighbour_list(self):
        a = io.read('aC.cfg')
        j, dr, i, abs_dr = neighbour_list("jDid", a, 1.85)

        self.assertTrue((np.bincount(i) == np.bincount(j)).all())

        r = a.get_positions()
        dr_direct = mic(r[j] - r[i], a.cell)

        abs_dr_from_dr = np.sqrt(np.sum(dr * dr, axis=1))
        abs_dr_direct = np.sqrt(np.sum(dr_direct * dr_direct, axis=1))

        self.assertTrue(np.all(np.abs(abs_dr - abs_dr_from_dr) < 1e-12))
        self.assertTrue(np.all(np.abs(abs_dr - abs_dr_direct) < 1e-12))

        self.assertTrue(np.all(np.abs(dr - dr_direct) < 1e-12))
Beispiel #7
0
    def test_neighbour_list(self):
        a = io.read('aC.cfg')
        j, dr, i, abs_dr = neighbour_list("jDid", a, 1.85)

        self.assertTrue((np.bincount(i) == np.bincount(j)).all())

        r = a.get_positions()
        dr_direct = mic(r[j]-r[i], a.cell)

        abs_dr_from_dr = np.sqrt(np.sum(dr*dr, axis=1))
        abs_dr_direct = np.sqrt(np.sum(dr_direct*dr_direct, axis=1))

        self.assertTrue(np.all(np.abs(abs_dr-abs_dr_from_dr) < 1e-12))
        self.assertTrue(np.all(np.abs(abs_dr-abs_dr_direct) < 1e-12))

        self.assertTrue(np.all(np.abs(dr-dr_direct) < 1e-12))
Beispiel #8
0
    def test_neighbour_list(self):
        for pbc in [True, False, [True, False, True]]:
            a = io.read('aC.cfg')
            a.set_pbc(pbc)
            j, dr, i, abs_dr, shift = neighbour_list("jDidS", a, 1.85)

            self.assertTrue((np.bincount(i) == np.bincount(j)).all())

            r = a.get_positions()
            dr_direct = mic(r[j]-r[i], a.cell)
            self.assertArrayAlmostEqual(r[j]-r[i]+shift.dot(a.cell), dr_direct)

            abs_dr_from_dr = np.sqrt(np.sum(dr*dr, axis=1))
            abs_dr_direct = np.sqrt(np.sum(dr_direct*dr_direct, axis=1))

            self.assertTrue(np.all(np.abs(abs_dr-abs_dr_from_dr) < 1e-12))
            self.assertTrue(np.all(np.abs(abs_dr-abs_dr_direct) < 1e-12))

            self.assertTrue(np.all(np.abs(dr-dr_direct) < 1e-12))
Beispiel #9
0
    def test_neighbour_list(self):
        for pbc in [True, False, [True, False, True]]:
            a = io.read('aC.cfg')
            a.set_pbc(pbc)
            j, dr, i, abs_dr, shift = neighbour_list("jDidS", a, 1.85)

            self.assertTrue((np.bincount(i) == np.bincount(j)).all())

            r = a.get_positions()
            dr_direct = mic(r[j]-r[i], a.cell)
            self.assertArrayAlmostEqual(r[j]-r[i]+shift.dot(a.cell), dr_direct)

            abs_dr_from_dr = np.sqrt(np.sum(dr*dr, axis=1))
            abs_dr_direct = np.sqrt(np.sum(dr_direct*dr_direct, axis=1))

            self.assertTrue(np.all(np.abs(abs_dr-abs_dr_from_dr) < 1e-12))
            self.assertTrue(np.all(np.abs(abs_dr-abs_dr_direct) < 1e-12))

            self.assertTrue(np.all(np.abs(dr-dr_direct) < 1e-12))
Beispiel #10
0
def compare_configurations(dislo, bulk, dislo_ref, bulk_ref,
                           alat, cylinder_r=None, print_info=True):
    """Compares two dislocation configurations based on the gradient of
       the displacements along the bonds.

    Parameters
    ----------
    dislo : ase.Atoms
        Dislocation configuration.
    bulk : ase.Atoms
        Corresponding bulk configuration for calculation of displacements.
    dislo_ref : ase.Atoms
        Reference dislocation configuration.
    bulk_ref : ase.Atoms
        Corresponding reference bulk configuration
        for calculation of displacements.
    alat : float
        Lattice parameter for calculation of neghbour list cutoff.
    cylinder_r : float or None
        Radius of region of comparison around the dislocation coreself.
        If None makes global comparison based on the radius of
        `dislo` configuration, else compares the regions with `cylinder_r`
        around the dislocation core position.
    print_info : bool
        Flag to switch print statement about the type of the comparison
    Returns
    -------
    float
        The Du norm of the differences per atom.

    """

    if cylinder_r is None:
        x, y, __ = bulk.positions.T
        radius = np.sqrt(x**2 + y**2)
        cutoff_radius = radius.max() - 10.

        if print_info:
            print("Making a global comparison with radius %.2f" % cutoff_radius)

    else:
        cutoff_radius = cylinder_r
        if print_info:
            print("Making a local comparison with radius %.2f" % cutoff_radius)

    x, y, __ = bulk_ref.positions.T
    radius = np.sqrt(x**2 + y**2)
    cutoff_mask = (radius < cutoff_radius)

    second_NN_distance = alat
    bulk_i, bulk_j = neighbour_list('ij', bulk_ref, second_NN_distance)

    I_core, J_core = np.array([(i, j) for i, j in zip(bulk_i, bulk_j) if cutoff_mask[i]]).T

    mapping = {}

    for i in range(len(bulk)):
        mapping[i] = np.linalg.norm(bulk_ref.positions -
                                    bulk.positions[i], axis=1).argmin()

    u_ref = dislo_ref.positions - bulk_ref.positions

    u = dislo.positions - bulk.positions
    u_extended = np.zeros(u_ref.shape)
    u_extended[mapping.values(), :] = u

    du = u_extended - u_ref

    Du = np.linalg.norm(np.linalg.norm(mic(du[J_core, :] - du[I_core, :],
                                           bulk.cell), axis=1))
    return Du
Beispiel #11
0
ref_frame = traj[0]

individual_elements = set(ref_frame.numbers)
s = '#{:>9s}'.format('frame')
if 'time' in ref_frame.info:
    s = '{} {:>10s}'.format(s, 'time')
s = '{} {:>10s}'.format(s, 'tot. rms')
for element in individual_elements:
    s = '{} {:>10s}'.format(s, 'rms ({})'.format(chemical_symbols[element]))
print(s)

last_frame = traj[0]
displacements = np.zeros_like(ref_frame.positions)
for i, frame in enumerate(traj[1:]):
    last_frame.set_cell(frame.cell, scale_atoms=True)
    cur_displacements = frame.positions - last_frame.positions
    cur_displacements = mic(cur_displacements, frame.cell, frame.pbc)
    displacements += cur_displacements

    s = '{:10}'.format(i+1)
    if 'time' in frame.info:
        s = '{} {:10.6}'.format(s, frame.info['time'])
    s = '{} {:10.6}'.format(s, np.sqrt((displacements**2).mean()))
    for element in individual_elements:
        s = '{} {:10.6}'.format(s, np.sqrt(
            (displacements[frame.numbers == element]**2).mean()))

    print(s)

    last_frame = frame