def atomic_strain(atoms_now, atoms_old, cutoff=None, i_now=None, j_now=None):
    """
    Calculate deformation gradient tensor and D^2_min measure for non-affine
    displacements.
    See: Falk, Langer, Phys. Rev. B 57, 7192 (1998)

    Parameters:
    -----------
    atoms_now      Current atomic configuration
    atoms_old      Reference atomic configuration
    cutoff         Neighbor list cutoff.
    i_now, j_now   Neighbor list. Automatically computed if not provided.

    Returns:
    --------
    delta_plus_epsilon  Strain gradient tensor
    d_sq                D^2_min norm
    """

    if i_now is None or j_now is None:
        if cutoff is None:
            raise ValueError('Please provide either neighbor list or neighbor '
                             'list cutoff.')

        # Create a particles object and set number of atoms and cell
        p = native.from_atoms(a_now)
        # create a neighbor list object and set it's cutoff
        nl = native.Neighbors(avgn)
        nl.request_interaction_range(cutoff)
        # get neighbours and distance
        i_now, j_now, abs_dr_now = nl.get_neighbors(p)
    elif cutoff is not None:
        raise ValueError('Please provide either neighbor list or neighbor '
                         'list cutoff, not both.')

    ### get the D square values
    delta_plus_epsilon, d_sq = get_D_square_min(atoms_now, atoms_old, i_now,
                                                j_now)

    return delta_plus_epsilon, d_sq
Calculate deformation gradient tensor and D^2_min measure for non-affine
    displacements.
    See: Falk, Langer, Phys. Rev. B 57, 7192 (1998)

    Parameters:
    -----------
    atoms_now      Current atomic configuration
    atoms_old      Reference atomic configuration
    cutoff         Neighbor list cutoff.
    i_now, j_now   Neighbor list. Automatically computed if not provided.

    Returns:
    --------
    delta_plus_epsilon  Strain gradient tensor
    d_sq                D^2_min norm