docs: 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