docs: def dn(self, fraction, n=None):
          r'''Computes the diameter at which a specified `fraction` of the 
          distribution falls under. Utilizes a bounded solver to search for the
          desired diameter.
  
          Parameters
          ----------
          fraction : float
              Fraction of the distribution which should be under the calculated
              diameter, [-]
          n : int, optional
              None (for the `order` specified when the distribution was created),
              0 (number), 1 (length), 2 (area), 3 (volume/mass),
              or any integer, [-]
  
          Returns
          -------
          d : float
              Particle size diameter, [m]
          
          Examples
          --------
          >>> psd = PSDLognormal(s=0.5, d_characteristic=5E-6, order=3)
          >>> psd.dn(.5)
          5e-06
          >>> psd.dn(1)
          0.00029474365335233776
          >>> psd.dn(0)
          0.0
          '''
          if fraction == 1.0:
              # Avoid returning the maximum value of the search interval
              fraction = 1.0 - epsilon
          if fraction < 0:
              raise ValueError('Fraction must be more than 0')
          elif fraction == 0:  # pragma: no cover
              if self.truncated:
                  return self.d_min
              return 0.0
              # Solve to float prevision limit - works well, but is there a real
              # point when with mpmath it would never happen?
              # dist.cdf(dist.dn(0)-1e-35) == 0
              # dist.cdf(dist.dn(0)-1e-36) == input
              # dn(0) == 1.9663615597466143e-20
  #            def err(d): 
  #                cdf = self.cdf(d, n=n)
  #                if cdf == 0:
  #                    cdf = -1
  #                return cdf
  #            return brenth(err, self.d_minimum, self.d_excessive, maxiter=1000, xtol=1E-200)
  
          elif fraction > 1:
              raise ValueError('Fraction less than 1')
          # As the dn may be incredibly small, it is required for the absolute 
          # tolerance to not be happy - it needs to continue iterating as long
          # as necessary to pin down the answer
          return brenth(lambda d:self.cdf(d, n=n) -fraction, 
                        self.d_minimum, self.d_excessive, maxiter=1000, xtol=1E-200)