8000 Test pvsystem.singlediode against precisely generated IV curves by reepoi · Pull Request #1573 · pvlib/pvlib-python · GitHub
[go: up one dir, main page]

Skip to content

Test pvsystem.singlediode against precisely generated IV curves #1573

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 29 commits into from
Mar 15, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
b92d376
start to adding tests from data in ivcurves repo
reepoi Sep 30, 2022
bebcfef
correcting Vth calculation
reepoi Oct 5, 2022
74c5f8c
making current increasing for numpy linear interp
reepoi Oct 16, 2022
85f83af
singlediode ivcurve_pnts does not give negative voltage with brentq a…
reepoi Oct 16, 2022
f165e08
adding test for singlediode log spacing methods
reepoi Oct 16, 2022
f27b97d
adding assertions for i_x and i_xx
reepoi Oct 16, 2022
64d6cef
adding i_x, i_xx iv curve data
reepoi Oct 16, 2022
8019f2c
updating whatsnew
reepoi Oct 16, 2022
2484dca
reverting changes to pvsystem.singlediode
reepoi Oct 31, 2022
dcaddc8
move precise iv curve fixtures into test_singlediode
reepoi Oct 31, 2022
3115bba
updating precise iv curve json to match new schema
reepoi Nov 17, 2022
150ee02
Merge branch 'main' of https://github.com/pvlib/pvlib-python into pre…
reepoi Nov 17, 2022
1c0f2b6
testing v_from_i, i_from_v
reepoi Nov 17, 2022
a98825e
small refactor
reepoi Nov 17, 2022
64f9c02
Merge branch 'main' of https://github.com/pvlib/pvlib-python into pre…
reepoi Dec 4, 2022
3537878
small refactor and update whatsnew
reepoi Dec 4, 2022
3670964
changing Boltzmann's constant
reepoi Dec 18, 2022
a27db19
add more to precise iv curve docstring
reepoi Dec 18, 2022
2c2ca4a
Merge branch 'main' of https://github.com/pvlib/pvlib-python into pre…
reepoi Dec 18, 2022
5178f87
Merge branch 'main' of https://github.com/pvlib/pvlib-python into pre…
reepoi Jan 10, 2023
a1040d3
use SciPy constants
reepoi Jan 10, 2023
99b9830
restore whatsnew 0.9.4
reepoi Jan 10, 2023
2471893
relax i_xx error tolerance
reepoi Jan 11, 2023
a13583b
trying lower i_xx atol
reepoi Jan 11, 2023
020e363
update generated iv curves after finding bug in their calcuation
reepoi Jan 16, 2023
be34c09
increasing i_xx atol, and adding comment about atol on mac, windows
reepoi Jan 23, 2023
e966f20
Merge branch 'main' of https://github.com/pvlib/pvlib-python into pre…
reepoi Mar 8, 2023
4b3016d
update whatsnew
reepoi Mar 8, 2023
5a6b631
update whatsnew and add references to test docs
reepoi Mar 15, 2023
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
Prev Previous commit
Next Next commit
move precise iv curve fixtures into test_singlediode
  • Loading branch information
reepoi committed Oct 31, 2022
commit dcaddc840c189ccb2a5590551fd1d9f750ebbce3
70 changes: 0 additions & 70 deletions pvlib/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -441,76 +441,6 @@ def cec_module_fs_495():
return parameters


def build_precise_iv_curve_dataframe(file_csv, file_json):
"""
Reads the data at ``file_csv`` and ``file_json`` to create a
data frame with these columns: ``Index``, ``photocurrent``,
``saturation_current``, ``resistance_series``, ``resistance_shunt``,
``n``, ``cells_in_series``, ``Voltages``, ``Currents``, ``v_oc``, ``i_sc``,
``v_mp``, ``i_mp``, ``p_mp``, ``i_x``, ``i_xx`, ``Temperature``,
``Irradiance``, ``Sweep Direction``, ``Datetime``, ``Boltzman``,
``Electron Charge``, and ``Vth``. The columns ``Irradiance``,
``Sweep Direction``, and ``Datetime`` are null or empty strings.

Parameters
----------
file_csv: str
Path to a CSV file of iv curve parameter sets.

file_json: str
Path to a JSON file of precise iv curves.

Returns
-------
A data frame.
"""
params = pd.read_csv(file_csv)
curves = pd.read_json(file_json)
curves = pd.DataFrame(curves['IV Curves'].values.tolist())
joined = params.merge(curves, on='Index', how='inner',
suffixes=(None, '_drop'), validate='one_to_one')
joined = joined[(c for c in joined.columns if not c.endswith('_drop'))]

joined['Boltzman'] = 1.380649e-23
joined['Electron Charge'] = 1.60217663e-19
joined['Vth'] = (
joined['Boltzman'] * joined['Temperature']
/ joined['Electron Charge']
)

return joined


@pytest.fixture(scope='function', params=[
{
'csv': f'{DATA_DIR}/precise_iv_curves_parameter_sets1.csv',
'json': f'{DATA_DIR}/precise_iv_curves1.json'
},
{
'csv': f'{DATA_DIR}/precise_iv_curves_parameter_sets2.csv',
'json': f'{DATA_DIR}/precise_iv_curves2.json'
}
], ids=[1, 2])
def precise_iv_curves(request):
file_csv, file_json = request.param['csv'], request.param['json']
return build_precise_iv_curve_dataframe(file_csv, file_json)


@pytest.fixture(scope='function', params=[
{
'csv': f'{DATA_DIR}/precise_iv_curves_parameter_sets1.csv',
'json': f'{DATA_DIR}/precise_iv_curves1_log_spacing.json'
},
{
'csv': f'{DATA_DIR}/precise_iv_curves_parameter_sets2.csv',
'json': f'{DATA_DIR}/precise_iv_curves2_log_spacing.json'
}
], ids=[1, 2])
def precise_iv_curves_log_spacing(request):
file_csv, file_json = request.param['csv'], request.param['json']
return build_precise_iv_curve_dataframe(file_csv, file_json)


@pytest.fixture(scope='function')
def sapm_temperature_cs5p_220m():
# SAPM temperature model parameters for Canadian_Solar_CS5P_220M
Expand Down
76 changes: 74 additions & 2 deletions pvlib/tests/test_singlediode.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
"""

import numpy as np
import pandas as pd
from pvlib import pvsystem
from pvlib.singlediode import (bishop88_mpp, estimate_voc, VOLTAGE_BUILTIN,
bishop88, bishop88_i_from_v, bishop88_v_from_i)
import pytest
from .conftest import DATA_DIR

POA = 888
TCELL = 55
Expand Down Expand Up @@ -69,18 +71,88 @@ def test_newton_fs_495(method, cec_module_fs_495):
assert np.isclose(pvs_ixx, ixx)


def build_precise_iv_curve_dataframe(file_csv, file_json):
"""
Reads a precise IV curve parameter set CSV and JSON to create a data frame
with these columns: ``Index``, ``photocurrent``, ``saturation_current``,
``resistance_series``, ``resistance_shunt``, ``n``, ``cells_in_series``,
``Voltages``, ``Currents``, ``v_oc``, ``i_sc``, ``v_mp``, ``i_mp``,
``p_mp``, ``i_x``, ``i_xx`, ``Temperature``, ``Irradiance``,
``Sweep Direction``, ``Datetime``, ``Boltzman``, ``Electron Charge``, and
``Vth``. The columns ``Irradiance``, ``Sweep Direction`` are null or empty
strings.

Parameters
----------
file_csv: str
Path to a CSV file of iv curve parameter sets.

file_json: str
Path to a JSON file of precise iv curves.

Returns
-------
A data frame.
"""
params = pd.read_csv(file_csv)
curves = pd.read_json(file_json)
curves = pd.DataFrame(curves['IV Curves'].values.tolist())
joined = params.merge(curves, on='Index', how='inner',
suffixes=(None, '_drop'), validate='one_to_one')
joined = joined[(c for c in joined.columns if not c.endswith('_drop'))]

joined['Boltzman'] = 1.380649e-23
joined['Electron Charge'] = 1.60217663e-19
Copy link
Contributor

Choose a reason for hiding this comment

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

For better traceability, I would think that the choice of values for these constants should documented as part of the files containing the parameters used to precisely compute the curves.

For comparison, scipy==1.8.1 gives:

scipy.constants.value("Boltzmann constant") = 1.380649e-23 J/K
scipy.constants.value("elementary charge") = 1.602176634e-19 C

Copy link
Contributor

Choose a reason for hiding this comment

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

Also see #483

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, I updated these constants to match The SI Brochure (https://www.bipm.org/en/publications/si-brochure) and cited that document in the docstring. In that docstring, I also added the precision cutoff of mpmath and more detail about the precision of the IV curve data. I avoided mentioning cwhanse/ivcurves, but maybe we should reference it. There is much more documentation and code that would help someone understand how the IV curve data was generated.

Also, if we use scipy.constants, pvlib may need to update its minimum SciPy version requirement because Boltzmann's constant changes depending on the SciPy version. The value for SciPy 1.9.3 is 1.602176634e-19 C, which matches the value hard-coded here; however, the value is 1.6021766208e-19 C for SciPy 1.2.0. It changes in SciPy 1.4.0, and pvlib's minimum version of SciPy is 1.2.0.

Copy link
Member

Choose a reason for hiding this comment

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

@pvlib/pvlib-maintainer I think we should advance scipy version and use the 2019 values, which are defined to be exact rather than with uncertainty.

joined['Vth'] = (
joined['Boltzman'] * joined['Temperature']
/ joined['Electron Charge']
)

return joined


@pytest.fixture(scope='function', params=[
{
'csv': f'{DATA_DIR}/precise_iv_curves_parameter_sets1.csv',
'json': f'{DATA_DIR}/precise_iv_curves1.json'
},
{
'csv': f'{DATA_DIR}/precise_iv_curves_parameter_sets2.csv',
'json': f'{DATA_DIR}/precise_iv_curves2.json'
}
], ids=[1, 2])
def precise_iv_curves(request):
file_csv, file_json = request.param['csv'], request.param['json']
return build_precise_iv_curve_dataframe(file_csv, file_json)


@pytest.fixture(scope='function', params=[
{
'csv': f'{DATA_DIR}/precise_iv_curves_parameter_sets1.csv',
'json': f'{DATA_DIR}/precise_iv_curves1_log_spacing.json'
},
{
'csv': f'{DATA_DIR}/precise_iv_curves_parameter_sets2.csv',
'json': f'{DATA_DIR}/precise_iv_curves2_log_spacing.j 67E6 son'
}
], ids=[1, 2])
def precise_iv_curves_log_spacing(request):
file_csv, file_json = request.param['csv'], request.param['json']
return build_precise_iv_curve_dataframe(file_csv, file_json)


@pytest.mark.parametrize('method', ['lambertw', 'brentq', 'newton'])
def test_singlediode_precision(method, precise_iv_curves):
"""
Tests the accuracy of singlediode. ivcurve_pnts is not tested.
"""
pc = precise_iv_curves
il, io, rs, rsh, nnsvt = (
x = (
pc['photocurrent'], pc['saturation_current'],
pc['resistance_series'], pc['resistance_shunt'],
pc['n'] * pc['cells_in_series'] * pc['Vth']
)
outs = pvsystem.singlediode(il, io, rs, rsh, nnsvt, method=method)
outs = pvsystem.singlediode(*x, method=method)

assert np.allclose(pc['i_sc'], outs['i_sc'], atol=1e-10, rtol=0)
assert np.allclose(pc['v_oc'], outs['v_oc'], atol=1e-10, rtol=0)
Expand Down
0