def test_get_J_srh():
    from solcore.analytic_solar_cells.depletion_approximation import forward, get_Jsrh

    T = np.random.uniform(0.1, 400)
    Vbi = np.random.uniform(0.1, 5)
    tp = np.power(10, np.random.uniform(-10, -5))
    tn = np.power(10, np.random.uniform(-10, -5))
    dEt = 0

    kT = kb * T
    V = np.linspace(-6, 4, 20)
    V = np.where(V < Vbi - 0.001, V, Vbi - 0.001)

    ni = np.power(10, np.random.uniform(2, 9))
    es = np.random.uniform(1, 20) * vacuum_permittivity
    Na = np.power(10, np.random.uniform(22, 25))
    Nd = np.power(10, np.random.uniform(22, 25))
    xi = np.power(10, np.random.uniform(-8, -5))

    wn = (-xi + np.sqrt(xi**2 + 2. * es * (Vbi - V) / q *
                        (1 / Na + 1 / Nd))) / (1 + Nd / Na)
    wp = (-xi + np.sqrt(xi**2 + 2. * es * (Vbi - V) / q *
                        (1 / Na + 1 / Nd))) / (1 + Na / Nd)

    w = wn + wp + xi

    expected = np.zeros(V.shape)

    inds = V >= -1120 * kT / q
    expected[inds] = forward(ni, V[inds], Vbi, tp, tn, w[inds], kT)

    result = get_Jsrh(ni, V, Vbi, tp, tn, w, kT, dEt)

    assert result == approx(expected, nan_ok=True)
def test_dark_iv_depletion_np(np_junction):
    from solcore.analytic_solar_cells.depletion_approximation import iv_depletion, get_depletion_widths, get_j_dark, get_Jsrh, identify_layers, identify_parameters
    from scipy.interpolate import interp1d

    test_junc, options = np_junction
    options.light_iv = False
    T = options.T

    test_junc[0].voltage = options.internal_voltages

    id_top, id_bottom, pRegion, nRegion, iRegion, pn_or_np = identify_layers(test_junc[0])
    xn, xp, xi, sn, sp, ln, lp, dn, dp, Nd, Na, ni, es = identify_parameters(test_junc[0], T, pRegion, nRegion, iRegion)

    niSquared = ni**2

    kbT = kb * T

    Vbi = (kbT / q) * np.log(Nd * Na / niSquared)

    V = np.where(test_junc[0].voltage < Vbi - 0.001, test_junc[0].voltage, Vbi - 0.001)

    wn, wp = get_depletion_widths(test_junc[0], es, Vbi, V, Na, Nd, xi)

    w = wn + wp + xi

    l_bottom, l_top = ln, lp
    x_bottom, x_top = xp, xn
    w_bottom, w_top = wp, wn
    s_bottom, s_top = sp, sn
    d_bottom, d_top = dp, dn
    min_bot, min_top = niSquared / Na, niSquared / Nd

    JtopDark = get_j_dark(x_top, w_top, l_top, s_top, d_top, V, min_top, T)
    JbotDark = get_j_dark(x_bottom, w_bottom, l_bottom, s_bottom, d_bottom, V, min_bot, T)

    JpDark, JnDark = JbotDark, JtopDark

    lifetime_n = ln ** 2 / dn
    lifetime_p = lp ** 2 / dp  # Jenny p163

    Jrec = get_Jsrh(ni, V, Vbi, lifetime_p, lifetime_n, w, kbT)

    J_sc_top = 0
    J_sc_bot = 0
    J_sc_scr = 0

    current = Jrec + JnDark + JpDark + V / 1e14- J_sc_top - J_sc_bot - J_sc_scr
    iv = interp1d(test_junc[0].voltage, current, kind='linear', bounds_error=False, assume_sorted=True,
                           fill_value=(current[0], current[-1]), copy=True)

    iv_depletion(test_junc[0], options)

    assert test_junc[0].iv(options.internal_voltages) == approx(iv(options.internal_voltages), nan_ok=True)