Skip to content

Speedup of singlediode._lambertw function #1010

@toddkarin

Description

@toddkarin

I have an application where I need to evaluate _lambertw many many times. Even a small speedup would be helpful. Currently _lambertw calculates IV curve points like I_x, I_xx that I don't need. What about adding an input flag that allows us to skip the evaluation of some parameters?

The version I wrote to do this is below, but there are other ways this could be done as well.

def _lambertw(photocurrent, saturation_current, resistance_series,
              resistance_shunt, nNsVth, ivcurve_pnts=None,
              calculate_all=False):
    if calculate_all:
        # Compute short circuit current
        i_sc = _lambertw_i_from_v(resistance_shunt, resistance_series, nNsVth,
                                  0.,
                                  saturation_current, photocurrent)

    # Compute open circuit voltage
    v_oc = _lambertw_v_from_i(resistance_shunt, resistance_series, nNsVth, 0.,
                              saturation_current, photocurrent)

    params = {'r_sh': resistance_shunt,
              'r_s': resistance_series,
              'nNsVth': nNsVth,
              'i_0': saturation_current,
              'i_l': photocurrent}

    # Find the voltage, v_mp, where the power is maximized.
    # Start the golden section search at v_oc * 1.14
    p_mp, v_mp = _golden_sect_DataFrame(params, 0., v_oc * 1.14,
                                        _pwr_optfcn)

    # Find Imp using Lambert W
    i_mp = _lambertw_i_from_v(resistance_shunt, resistance_series, nNsVth,
                              v_mp, saturation_current, photocurrent)

    if calculate_all:
        # Find Ix and Ixx using Lambert W
        i_x = _lambertw_i_from_v(resistance_shunt, resistance_series, nNsVth,
                                 0.5 * v_oc, saturation_current, photocurrent)

        i_xx = _lambertw_i_from_v(resistance_shunt, resistance_series, nNsVth,
                                  0.5 * (v_oc + v_mp), saturation_current,
                                  photocurrent)

    if calculate_all:
        out = (i_sc, v_oc, i_mp, v_mp, p_mp, i_x, i_xx)
    else:
        out = (v_oc, i_mp, v_mp, p_mp)

    # create ivcurve
    if ivcurve_pnts:
        ivcurve_v = (np.asarray(v_oc)[..., np.newaxis] *
                     np.linspace(0, 1, ivcurve_pnts))

        ivcurve_i = _lambertw_i_from_v(resistance_shunt, resistance_series,
                                       nNsVth, ivcurve_v.T, saturation_current,
                                       photocurrent).T

        out += (ivcurve_i, ivcurve_v)

    return out

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions