docs: def _NTU_from_P_solver(P1, R1, NTU_min, NTU_max, function, **kwargs):
      '''Private function to solve the P-NTU method backwards, given the
      function to use, the upper and lower NTU bounds for consideration,
      and the desired P1 and R1 values.
      '''
      P1_max = _NTU_from_P_objective(NTU_max, R1, 0, function, **kwargs)
      P1_min = _NTU_from_P_objective(NTU_min, R1, 0, function, **kwargs)
      if P1 > P1_max:
          raise ValueError('No solution possible gives such a high P1; maximum P1=%f at NTU1=%f' %(P1_max, NTU_max))
      if P1 < P1_min:
          raise ValueError('No solution possible gives such a low P1; minimum P1=%f at NTU1=%f' %(P1_min, NTU_min))
      # Construct the function as a lambda expression as solvers don't support kwargs
      to_solve = lambda NTU1: _NTU_from_P_objective(NTU1, R1, P1, function, **kwargs)
      return ridder(to_solve, NTU_min, NTU_max)