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.

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)