Skip to content

Bishop88 functions sometimes return incorrect results or errors when using d2mutau and NsVbi parameters #2013

Closed
@kandersolar

Description

@kandersolar

Describe the bug
The bishop88 functions can sometimes fail, or return incorrect results, when using the d2mutau and NsVbi parameters.

To Reproduce

Set-up:

import pvlib
import numpy as np
import matplotlib.pyplot as plt

sdm_params = {
    'alpha_sc': 0.001, 'gamma_ref': 1.409, 'mu_gamma': 0.001, 'I_o_ref': 3.96e-11,
    'R_sh_ref': 4900, 'R_sh_0': 8800, 'R_sh_exp': 5.5,
    'R_s': 6.76, 'cells_in_series': 264, 'EgRef': 1.121, 'I_L_ref': 2.278883384981941
}
d2mutau = 1.5
NsVbi = 237.6

G = np.linspace(0, 1200)
T = 25
sde_params = pvlib.pvsystem.calcparams_pvsyst(G, T, **sdm_params)

method='brentq' errors with ValueError: f(a) and f(b) must have different signs.

Click to show traceback
Traceback (most recent call last):

  Cell In[16], line 17
    mpp = pvlib.singlediode.bishop88_mpp(*sde_params, d2mutau=d2mutau, NsVbi=NsVbi, method='brentq')

  File ~\software\miniconda3\envs\dev\lib\site-packages\pvlib\singlediode.py:577 in bishop88_mpp
    vd = vec_fun(voc_est, *args)

  File ~\software\miniconda3\envs\dev\lib\site-packages\numpy\lib\function_base.py:2372 in __call__
    return self._call_as_normal(*args, **kwargs)

  File ~\software\miniconda3\envs\dev\lib\site-packages\numpy\lib\function_base.py:2365 in _call_as_normal
    return self._vectorize_call(func=func, args=vargs)

  File ~\software\miniconda3\envs\dev\lib\site-packages\numpy\lib\function_base.py:2450 in _vectorize_call
    ufunc, otypes = self._get_ufunc_and_otypes(func=func, args=args)

  File ~\software\miniconda3\envs\dev\lib\site-packages\numpy\lib\function_base.py:2410 in _get_ufunc_and_otypes
    outputs = func(*inputs)

  File ~\software\miniconda3\envs\dev\lib\site-packages\pvlib\singlediode.py:572 in <lambda>
    vbr_exp: brentq(fmpp, 0.0, voc,

  File ~\software\miniconda3\envs\dev\lib\site-packages\scipy\optimize\_zeros_py.py:809 in brentq
    r = _zeros._brentq(f, a, b, xtol, rtol, maxiter, args, full_output, disp)

ValueError: f(a) and f(b) must have different signs

method='newton' gives incorrect results for some conditions:

mpp_newton = pvlib.singlediode.bishop88_mpp(*sde_params, d2mutau=d2mutau, NsVbi=NsVbi, method='newton')
plt.plot(G, mpp_newton[2])
plt.ylabel('$P_{mp}$ [W]')
plt.xlabel('Irradiance [W/m2]')

image

Versions:

  • pvlib.__version__: 0.10.4
  • scipy.__version__: 1.12.0

Additional context
I think the problem has something to do with the following:

  1. The SDE with the thin film recombination current term has a singularity at NsVbi = Vd, and our code only returns valid results for Vd < NsVbi (ref Adding New Single Diode Model For CdTe #163 (comment))
  2. estimate_voc can sometimes return a value on the other side of the singularity (Vd > NsVbi), where our bishop88-style calculations are not valid.
  3. bishop88_mpp uses estimate_voc to calculate either an upper bound for the bracketed optimization (with method='brentq') or the initial guess (with method='newton'), meaning we are sometimes providing invalid starting points to the root finder.

Here is an example of the estimated Voc being greater than NsVbi:

import pvlib

sdm_params = {
    'alpha_sc': 0.001, 'gamma_ref': 1.409, 'mu_gamma': 0.001, 'I_o_ref': 3.96e-11,
    'R_sh_ref': 4900, 'R_sh_0': 8800, 'R_sh_exp': 5.5,
    'R_s': 6.76, 'cells_in_series': 264, 'EgRef': 1.121, 'I_L_ref': 2.278883384981941
}
d2mutau = 1.5
NsVbi = 237.6

G = 1100
T = 25

sde_params = pvlib.pvsystem.calcparams_pvsyst(G, T, **sdm_params)
voc_est = pvlib.singlediode.estimate_voc(sde_params[0], sde_params[1], sde_params[-1])
print(voc_est)  # 237.6945087345138, greater than NsVbi=237.6

cc @leliadeville

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions