docs: def psd_spacing(d_min=None, d_max=None, pts=20, method='logarithmic'):
      r'''Create a particle spacing mesh in one of several ways for use in
      modeling discrete particle size distributions. The allowable meshes are
      'linear', 'logarithmic', a geometric series specified by a Renard number
      such as 'R10', or the meshes available in one of several sieve standards.
      
      Parameters
      ----------
      d_min : float, optional
          The minimum diameter at which the mesh starts, [m]
      d_max : float, optional
          The maximum diameter at which the mesh ends, [m]
      pts : int, optional
          The number of points to return for the mesh (note this is not respected
          by sieve meshes), [-]
      method : str, optional
          Either 'linear', 'logarithmic', a Renard number like 'R10' or 'R5' or
          'R2.5', or one of the sieve standards 'ISO 3310-1 R40/3', 
          'ISO 3310-1 R20', 'ISO 3310-1 R20/3', 'ISO 3310-1', 'ISO 3310-1 R10', 
          'ASTM E11', [-]
  
      Returns
      -------
      ds : list[float]
          The generated mesh diameters, [m]
  
      Notes
      -----
      Note that when specifying a Renard series, only one of `d_min` or `d_max` can
      be respected! Provide only one of those numbers. 
      
      Note that when specifying a sieve standard the number of points is not
      respected!
  
      Examples
      --------
      >>> psd_spacing(d_min=5e-5, d_max=5e-4, method='ISO 3310-1 R20/3')
      [6.3e-05, 9e-05, 0.000125, 0.00018, 0.00025, 0.000355, 0.0005]
  
      References
      ----------
      .. [1] ASTM E11 - 17 - Standard Specification for Woven Wire Test Sieve 
         Cloth and Test Sieves.
      .. [2] ISO 3310-1:2016 - Test Sieves -- Technical Requirements and Testing
         -- Part 1: Test Sieves of Metal Wire Cloth.
      '''
      if method == 'logarithmic':
          return logspace(log10(d_min), log10(d_max), pts)
      elif method == 'linear':
          return linspace(d_min, d_max, pts)
      elif method[0] in ('R', 'r'):
          ratio = 10**(1.0/float(method[1:]))
          if d_min is not None and d_max is not None:
              raise Exception('For geometric (Renard) series, only '
                              'one of `d_min` and `d_max` should be provided')
          if d_min is not None:
              ds = [d_min]
              for i in range(pts-1):
                  ds.append(ds[-1]*ratio)
              return ds
          elif d_max is not None:
              ds = [d_max]
              for i in range(pts-1):
                  ds.append(ds[-1]/ratio)
              return list(reversed(ds))
      elif method in sieve_spacing_options:
          l = sieve_spacing_options[method]
          ds = []
          for sieve in l:
             if  d_min <= sieve.opening <= d_max:
                 ds.append(sieve.opening)
          return list(reversed(ds))
      else:
          raise Exception('Method not recognized')