Skip to content
Merged
Show file tree
Hide file tree
Changes from 45 commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
f475120
initial commit fit_cec_using_sam
cwhanse May 3, 2019
7454e4d
outline ivcurves
cwhanse May 3, 2019
9c5e1a9
use nrel-pysam
cwhanse May 6, 2019
593f355
remove sam_dir
cwhanse May 7, 2019
4ab1fed
add Sandia single curve fit
cwhanse May 7, 2019
8a8890f
complete function
cwhanse May 9, 2019
b72b0b4
add test, move code to ivtools.py
cwhanse May 10, 2019
921aea8
remove single files
cwhanse May 10, 2019
4f4ad0f
Merge branch 'master' of https://github.com/pvlib/pvlib-python into i…
cwhanse May 13, 2019
eaee814
change PySCC usage to wrapper
May 14, 2019
d65067b
Merge branch 'master' of https://github.com/pvlib/pvlib-python into i…
May 14, 2019
4744bde
add nrel-pysam to ci/requirements
May 14, 2019
aae2731
stickler, add pysam version in ci/requirements
May 14, 2019
e1697b0
does case matter?
May 14, 2019
e779c7a
remove pysam for py27, move import pysam to try/except
May 14, 2019
b0f0a9d
add requires_scipy
May 14, 2019
df33113
rename variables for style guide
May 14, 2019
bec1915
Merge branch 'master' of https://github.com/pvlib/pvlib-python into i…
May 15, 2019
b64cf57
add test for fit_cec_with_sam
May 18, 2019
c8004ff
fix conflict in requirements
May 18, 2019
586a134
fix typo, raise syntax
May 18, 2019
6d6733d
remove ivtools dir
May 18, 2019
98af4ff
fix pytest fixture usage
cwhanse May 18, 2019
26c8f38
linter, fix np.allclose
cwhanse May 18, 2019
1deb148
relax test condition
cwhanse May 18, 2019
3c66a1d
resolve merge conflict
cwhanse May 24, 2019
8308635
remove try/except, add to docstring, use helper functions
cwhanse May 24, 2019
2601dc5
Merge branch 'master' of https://github.com/pvlib/pvlib-python into i…
cwhanse May 27, 2019
632234e
add requires_pysam
cwhanse May 28, 2019
d975f32
fix import
cwhanse May 28, 2019
37a362d
fix infinite loop
cwhanse May 28, 2019
c956486
update whatsnew, api.rst
cwhanse May 28, 2019
bbd5720
fix lint errors
cwhanse May 28, 2019
01f0dba
lint
cwhanse May 28, 2019
a32bb35
resolve comments
cwhanse Jun 12, 2019
5779b1e
comment response
Jun 18, 2019
0f45925
fix function name in test
Jun 18, 2019
58070da
more comment responses
Jun 20, 2019
9bf7566
add nan output to fit_cec_sam, comment responses
cwhanse Jun 21, 2019
723b454
lint
cwhanse Jun 21, 2019
ad9bc2d
consistent return nan, v_oc arg etc. defaults to None, edit description
cwhanse Jun 24, 2019
6d5ff04
initialize failed
cwhanse Jun 24, 2019
d506140
lint
cwhanse Jun 24, 2019
2517b33
implement exception for failed fitting
cwhanse Jun 25, 2019
320ebf9
remove requirement for sorted i
cwhanse Jun 27, 2019
d66701c
update internal variable name for consistency
cwhanse Jul 12, 2019
fe4bdfe
Merge branch 'ivtools' of https://github.com/cwhanse/pvlib-python int…
cwhanse Jul 12, 2019
6879b36
Merge branch 'master' of https://github.com/pvlib/pvlib-python into i…
cwhanse Jul 12, 2019
0328755
add to __init__.py
cwhanse Jul 16, 2019
cff625b
code style changes
cwhanse Jul 16, 2019
f8a4860
lint
cwhanse Jul 16, 2019
e8be716
adjust error messaging in _calculate_sde_parameters
cwhanse Jul 16, 2019
9af20f7
edits to units in docstring
cwhanse Jul 16, 2019
ee19ed1
change error handling in fit_sde_sandia, docstring reformat
cwhanse Jul 16, 2019
aa47f48
fix tests, docstring edits
cwhanse Jul 16, 2019
e55330f
test math formatting
cwhanse Jul 17, 2019
fb3be8c
more edits to docstring
cwhanse Jul 17, 2019
efe1cfb
multiline raw string
cwhanse Jul 17, 2019
8d68c8c
try another approach
cwhanse Jul 17, 2019
ec6fee5
move r
cwhanse Jul 17, 2019
0270633
change function name, docstring edits
cwhanse Jul 17, 2019
6a3735e
update function name
cwhanse Jul 17, 2019
227d8b5
add math delimiters
cwhanse Jul 17, 2019
16ab69f
remove delimiter, use indent
cwhanse Jul 17, 2019
11b8dda
fix alignment in docstring
cwhanse Jul 17, 2019
f84000d
some edits to docstring format
cwhanse Jul 18, 2019
6cd1095
change name back to sde
cwhanse Jul 23, 2019
dde20b5
add bad IV curves for coverage test
cwhanse Jul 23, 2019
4c39e2a
separate bad IV test, fix test
cwhanse Jul 23, 2019
eab687a
lint
cwhanse Jul 23, 2019
c02a1ab
update api.rst and whatsnew
cwhanse Jul 24, 2019
d6e21b7
Merge branch 'master' of https://github.com/pvlib/pvlib-python into i…
cwhanse Aug 2, 2019
012ef50
merge conflicts
cwhanse Sep 10, 2019
b8a713b
hardwire test output rather than read from old CEC file
cwhanse Sep 10, 2019
3aae45a
test fix
cwhanse Sep 10, 2019
35b90e5
really fix it this time
cwhanse Sep 10, 2019
fe89a87
fix raise statement
cwhanse Sep 10, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ci/requirements-py35.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@ dependencies:
- shapely # pvfactors dependency
- siphon # conda-forge
- pip:
- nrel-pysam
- pvfactors==1.0.1
1 change: 1 addition & 0 deletions ci/requirements-py36.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@ dependencies:
- shapely # pvfactors dependency
- siphon # conda-forge
- pip:
- nrel-pysam
- pvfactors==1.0.1
1 change: 1 addition & 0 deletions ci/requirements-py37.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@ dependencies:
- shapely # pvfactors dependency
- siphon # conda-forge
- pip:
- nrel-pysam
- pvfactors==1.0.1
8 changes: 8 additions & 0 deletions docs/sphinx/source/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,14 @@ PVsyst model

pvsystem.pvsyst_celltemp

Functions for fitting PV models
-------------------------------
.. autosummary::
:toctree: generated/

ivtools.fit_sde_sandia
ivtools.fit_cec_sam
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe fit_single_diode_cec_sam to more closely mimic the sandia function?

Copy link
Contributor

@markcampanelli markcampanelli Jul 20, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I kinda like the single-diode equation (SDE) vs. single-diode model (SDM) distinction, and I don’t mind the abbreviations if they are expanded in the docstring. This leads to something succinct and descriptive like:

fit_sde_sandia
fit_sdm_cec_sam

action_thing[_variant]_source

I don’t know if you want to add a variant to the SDE (to cover potential variants, such as with a reverse breakdown component). Also, the variant and source could repeat in some cases, leading to some stuttering.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@markcampanelli good suggestion for naming patterns. There are two different applications here: fitting the SD equation to an IV curve, and fitting a SD model (a set of equations) to some data (in the case of the CEC model and the SAM method, datasheet information). I changed sde to single_diode in one function name, but I don't care for single_diode_equation and single_diode_model in the names.

I'm going to open a new issue to extend the single diode documentation to lay out the terminology: single diode equation, single diode model, 5 parameters vs. model parameters.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works for me.


Other
-----

Expand Down
22 changes: 22 additions & 0 deletions docs/sphinx/source/whatsnew/v0.7.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,30 @@ recommend all users of v0.6.3 upgrade to this release.

**Python 2.7 support ended on June 1, 2019**. (:issue:`501`)

API Changes
~~~~~~~~~~~


Enhancements
~~~~~~~~~~~~
* Add `ivtools` module to contain functions for IV model fitting.
* Add :py:func:`~pvlib.ivtools.fit_sde_sandia`, a simple method to fit the
single diode equation to an IV curve.
* Add :py:func:`~pvlib.ivtools.fit_cec_sam`, a wrapper to access the
model fitting function '6parsolve' from NREL's System Advisor Model.


Bug fixes
~~~~~~~~~


Testing
~~~~~~~


Contributors
~~~~~~~~~~~~
* Mark Campanellli (:ghuser:`markcampanelli`)
* Will Holmgren (:ghuser:`wholmgren`)
* Cliff Hansen (:ghuser:`cwhanse`)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

blank line

334 changes: 334 additions & 0 deletions pvlib/ivtools.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,334 @@
# -*- coding: utf-8 -*-
"""
Created on Fri Mar 29 10:34:10 2019

@author: cwhanse
"""

import numpy as np


def fit_cec_sam(celltype, v_mp, i_mp, v_oc, i_sc, alpha_sc, beta_voc,
gamma_pmp, cells_in_series, temp_ref=25):
'''
Estimates parameters for the CEC single diode model [1] using the SAM SDK.

Parameters
----------
celltype : str
Value is one of 'monoSi', 'multiSi', 'polySi', 'cis', 'cigs', 'cdte',
'amorphous'
v_mp : float
Voltage at maximum power point [V]
i_mp : float
Current at maximum power point [A]
v_oc : float
Open circuit voltage [V]
i_sc : float
Short circuit current [A]
alpha_sc : float
Temperature coefficient of short circuit current [A/C]
beta_voc : float
Temperature coefficient of open circuit voltage [V/C]
gamma_pmp : float
Temperature coefficient of power at maximum point point [%/C]
cells_in_series : int
Number of cells in series
temp_ref : float, default 25C
Reference temperature condition

Returns
-------
tuple of the following elements:

a_ref : float
The product of the usual diode ideality factor ``n`` (unitless),
number of cells in series ``Ns``, and cell thermal voltage at
reference conditions [V]

I_L_ref : float
The light-generated current (or photocurrent) at reference
conditions [A]

I_o_ref : float
The dark or diode reverse saturation current at reference
conditions [A]

R_sh_ref : float
The shunt resistance at reference conditions, in ohms.

R_s : float
The series resistance at reference conditions, in ohms.

Adjust : float
The adjustment to the temperature coefficient for short circuit
current, in percent.

Raises:
ImportError if NREL-PySAM is not installed.
RuntimeError if parameter extraction is not successful.

Notes
-----
Inputs ``v_mp``, ``v_oc``, ``i_mp`` and ``i_sc`` are assumed to be from a
single IV curve at constant irradiance and cell temperature. Irradiance is
not explicitly used by the fitting procedure. The irradiance level at which
the input IV curve is determined and the specified cell temperature
``Tref`` are the reference conditions for the output parameters
``I_L_ref``, ``I_o_ref``, ``R_sh_ref``, ``R_s`` and ``Adjust``.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think Tref should be temp_ref, and a_ref should be included in the output parameters list.


References
----------
[1] A. Dobos, "An Improved Coefficient Calculator for the California
Energy Commission 6 Parameter Photovoltaic Module Model", Journal of
Solar Energy Engineering, vol 134, 2012.
'''

try:
from PySAM import PySSC
except ImportError as e:
raise("Requires NREL's PySAM package at "
"https://pypi.org/project/NREL-PySAM/.") from e

datadict = {'tech_model': '6parsolve', 'financial_model': 'none',
'celltype': celltype, 'Vmp': v_mp,
'Imp': i_mp, 'Voc': v_oc, 'Isc': i_sc, 'alpha_isc': alpha_sc,
'beta_voc': beta_voc, 'gamma_pmp': gamma_pmp,
'Nser': cells_in_series, 'Tref': temp_ref}

result = PySSC.ssc_sim_from_dict(datadict)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to check for fitting success before assigning results, because dictionary entries are apparently missing altogether when it fails causing a KeyError at assignment:

if result['cmod_success'] == 1:
    # Assign everything
else:
    # Assign nan's like in fit_sde_sandia()?

This behavior also needs to be tested and documented.

Here's how I broke it:

v_mp = 0.45
i_mp = 5.25
v_oc = 0.55
i_sc = 5.5
alpha_sc = 0.0005 * i_sc
beta_voc = 0.005 * v_oc
gamma_pmp = 0.0055
cells_in_series = 1
temp_ref = 25
for celltype in ['monoSi', 'multiSi', 'polySi', 'cis', 'cigs', 'cdte', 'amorphous']:
    ivtools.fit_cec_sam(celltype, v_mp, i_mp, v_oc, i_sc, alpha_sc, beta_voc, gamma_pmp, cells_in_series, temp_ref)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

if result['cmod_success'] == 1:
return tuple([result[k] for k in ['Il', 'Io', 'Rsh', 'Rs', 'a',
'Adj']])
else:
raise RuntimeError('Parameter estimation failed')


def fit_sde_sandia(v, i, v_oc=None, i_sc=None, mp=None, vlim=0.2, ilim=0.1):
""" Fits the single diode equation to an IV curve.

Parameters
----------
v : ndarray
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

was voltage previously discussed and rejected? pvlib code style says to prefer full names when possible. I have no problem with mixing up full names and abbreviations in the API if others prefer e.g. (voltage, current, v_oc, i_sc...). My main objection is to single letter variables.

1D array of `float` type containing voltage at each point on the IV
curve, increasing from 0 to v_oc inclusive [V]

i : ndarray
1D array of `float` type containing current at each point on the IV
curve, from i_sc to 0 inclusive, of `float` type [A]

v_oc : float, default None
Open circuit voltage [V]. If not provided, ``v_oc`` is taken as
``v[-1]``.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer: ...taken as last point of voltage array


i_sc : float, default None
Short circuit current [A]. If not provided, ``i_sc`` is taken as
``i[0]``.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above


mp : tuple of float, default None
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest v_mp_i_mp

Voltage, current at maximum power point in units of [V], [A].
If not provided, values are found from inputs ``v`` and ``i``.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just reading the docstring so far has me wondering exactly how they will be found in the code, but maybe that ambiguity is ok...


vlim : float, default 0.2
defines portion of IV curve where the exponential term in the single
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

D

diode equation can be neglected, i.e. V <= vlim * v_oc [V]

ilim : float, default 0.1
defines portion of the IV curve where the exponential term in the
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

D

single diode equation is signficant, approximately defined by
I < (1 - ilim) * i_sc [A]

Returns
-------
tuple of the following elements:

photocurrent : float
photocurrent [A]

saturation_current : float
dark (saturation) current [A]

resistance_shunt : float
shunt (parallel) resistance, ohm

resistance_series : float
series resistance, ohm

nNsVth : float
product of thermal voltage ``Vth`` [V], diode ideality factor
``n``, and number of series cells ``Ns``

Raises:
RuntimeError if parameter extraction is not successful.

Notes
-----
Inputs ``v``, ``i``, ``v_mp``, ``v_oc``, ``i_mp`` and ``i_sc`` are assumed
to be from a single IV curve at constant irradiance and cell temperature.

:py:func:`fit_sde_sandia` obtains values for the five parameters for the
single diode equation [1]:

.. math::

I = IL - I0*[exp((V+I*Rs)/(nNsVth))-1] - (V + I*Rs)/Rsh

:py:func:`pvsystem.singlediode` for definition of the parameters.

The extraction method [2] proceeds in four steps:
1) In the single diode equation, replace Rsh = 1/Gp and re-arrange
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

have you checked if this renders as desired? I believe you need a blank line after the colon and a period instead of parenthesis

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't render correct. Do you know of a summary of latex commands available in rst? what I know in latex, doesn't work.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In docstring I often have to escape latex twice or preface the entire for string with raw: r"""\beta""" or """\\beta"""


.. math::

I = IL - I0*exp((V+I*Rs)/(nNsVth) - 1) - (V + I*Rs)/Rsh

.. math::

I = IL/(1+Gp*Rs) - (Gp*V)/(1+Gp*Rs) -
I0/(1+Gp*Rs)*exp((V+I*Rs)/(nNsVth) - 1)

2) fit the linear portion of the IV curve defined as V <= vlim * v_oc,
where I0/(1+Gp*Rs)*exp((V+I*Rs)/(nNsVth) - 1) ≈ 0

.. math::

I ~ IL/(1+Gp*Rs) - (Gp*V)/(1+Gp*Rs) = beta0 + beta1*V

3) fit the exponential portion of the IV curve defined by
beta0 + beta1*V - I > ilim * i_sc, where
exp((V+I*Rs)/(nNsVth)) >> 1 so that
exp((V+I*Rs)/(nNsVth)) - 1 ≈ exp((V+I*Rs)/(nNsVth))

.. math::

log(beta0 - beta1*V - I) ~ log((I0)/(1+Gp*Rs)) + (V)/(nNsVth) +
(Rs*I)/(nNsVth) = beta2 + beta3*V + beta4*I

4) calculate values for ``IL, I0, Rs, Rsh,`` and ``nNsVth`` from the
regression coefficents beta0, beta1, beta3 and beta4.


References
----------
[1] S.R. Wenham, M.A. Green, M.E. Watt, "Applied Photovoltaics" ISBN
0 86758 909 4
[2] C. B. Jones, C. W. Hansen, Single Diode Parameter Extraction from
In-Field Photovoltaic I-V Curves on a Single Board Computer, 46th IEEE
Photovoltaic Specialist Conference, Chicago, IL, 2019
"""

# If not provided, extract v_oc, i_sc, v_mp and i_mp from the IV curve data
if v_oc is None:
v_oc = v[-1]
if i_sc is None:
i_sc = i[0]
if mp is not None:
v_mp, i_mp = mp
else:
v_mp, i_mp = _find_mp(v, i)

# Find beta0 and beta1 from linear portion of the IV curve
beta0, beta1 = _find_beta0_beta1(v, i, vlim, v_oc)

if not np.isnan(beta0):
beta3, beta4 = _find_beta3_beta4(v, i, beta0, beta1, ilim, i_sc)

# calculate single diode parameters from regression coefficients
result = _calculate_sde_parameters(beta0, beta1, beta3, beta4, v_mp, i_mp,
v_oc)

if result is None:
raise RuntimeError("Parameter extraction failed. Try increasing the"
"number of data points in the IV curve")
else:
IL, I0, Rsh, Rs, nNsVth = result
return IL, I0, Rsh, Rs, nNsVth
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as just return result imo extra line is not needed, contract is already defined in docstring under "Returns", but not a blocker if this is a style or readability issue



def _find_mp(v, i):
"""
Finds voltage and current at maximum power point.

Parameters
----------
v : ndarray
1D array containing voltage at each point on the IV curve, increasing
from 0 to v_oc inclusive, of `float` type [V]

i : ndarray
1D array containing current at each point on the IV curve, decreasing
from i_sc to 0 inclusive, of `float` type [A]

Returns
-------
v, i : tuple
voltage ``v`` and current ``i`` at the maximum power point [V], [A]
"""
p = v * i
idx = np.argmax(p)
return v[idx], i[idx]


def _calc_I0(IL, I, V, Gp, Rs, beta3):
return (IL - I - Gp * V - Gp * Rs * I) / np.exp(beta3 * (V + Rs * I))


def _find_beta0_beta1(v, i, vlim, v_oc):
# Get intercept and slope of linear portion of IV curve.
# Start with V =< vlim * v_oc, extend by adding points until slope is
# negative (downward).
beta0 = np.nan
beta1 = np.nan
idx = np.searchsorted(v, vlim * v_oc)
while idx <= len(v):
coef = np.polyfit(v[:idx], i[:idx], deg=1)
if coef[0] < 0:
# intercept term
beta0 = coef[1].item()
# sign change of slope to get positive parameter value
beta1 = -coef[0].item()
break
else:
idx += 1
return beta0, beta1


def _find_beta3_beta4(v, i, beta0, beta1, ilim, i_sc):
# Subtract the IV curve from the linear fit.
y = beta0 - beta1 * v - i
x = np.array([np.ones_like(v), v, i]).T
# Select points where y > ilim * i_sc to regress log(y) onto x
result = np.linalg.lstsq(x[y > ilim * i_sc], np.log(y[y > ilim * i_sc]),
rcond=None)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like this would fit on one line

coef = result[0]
beta3 = coef[1].item()
beta4 = coef[2].item()
return beta3, beta4


def _calculate_sde_parameters(beta0, beta1, beta3, beta4, v_mp, i_mp, v_oc):
failed = False
if any(np.isnan([beta0, beta1, beta3, beta4])):
failed = True
Copy link
Member

@mikofski mikofski Jul 16, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Zen of python says explicit is better.

Here and below, and then above in the calling function, imo use exceptions and propagate them up.

  • remove failed = False

  • instead of failed = True, use raise RuntimeError("beta coefficient was NaN")

  • remove else and dedent, because next block can't be reached if no error

  • on line 322, check I0

    if (I0_vmp <= 0) and (I0_voc <= 0):
        raise RuntimeError("I0 was less than zero")
    
  • remove if failed: results = None and remove else, then just return IL, I0, Rsh, Rs, nNsVth

  • finally in fit_sde_sandia on line 240 instead of if result is None: either just remove that section and do nothing, because you are already raising an exception, or place a try above and put except there instead, to modify the message.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm all for improving the code for others to understand. One challenge here is that np.linalg.lstsq and np.polyfit throw an unhelpful "does not converge" error if there is any NaN in the data. I want to avoid exiting with that error while assigning np.nan to SDE parameters that aren't determined.

else:
nNsVth = 1.0 / beta3
Rs = beta4 / beta3
Gp = beta1 / (1.0 - Rs * beta1)
Rsh = 1.0 / Gp
IL = (1 + Gp * Rs) * beta0
# calculate I0
I0_v_mp = _calc_I0(IL, i_mp, v_mp, Gp, Rs, beta3)
I0_v_oc = _calc_I0(IL, 0, v_oc, Gp, Rs, beta3)
if (I0_v_mp > 0) and (I0_v_oc > 0):
I0 = 0.5 * (I0_v_mp + I0_v_oc)
elif (I0_v_mp > 0):
I0 = I0_v_mp
elif (I0_v_oc > 0):
I0 = I0_v_oc
else:
failed = True
if failed:
result = None
else:
result = (IL, I0, Rsh, Rs, nNsVth)
return result
Loading