pvlib 0.11.2__py3-none-any.whl → 0.12.1a1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pvlib/__init__.py +1 -0
- pvlib/atmosphere.py +40 -40
- pvlib/bifacial/infinite_sheds.py +4 -3
- pvlib/bifacial/utils.py +2 -1
- pvlib/iotools/__init__.py +6 -0
- pvlib/iotools/psm3.py +1 -1
- pvlib/iotools/psm4.py +819 -0
- pvlib/iotools/pvgis.py +10 -2
- pvlib/iotools/tmy.py +3 -69
- pvlib/irradiance.py +38 -15
- pvlib/ivtools/sdm/__init__.py +20 -0
- pvlib/ivtools/sdm/_fit_desoto_pvsyst_sandia.py +585 -0
- pvlib/ivtools/sdm/cec.py +93 -0
- pvlib/ivtools/sdm/desoto.py +401 -0
- pvlib/ivtools/sdm/pvsyst.py +630 -0
- pvlib/location.py +73 -33
- pvlib/modelchain.py +19 -36
- pvlib/pvsystem.py +114 -65
- pvlib/snow.py +64 -28
- pvlib/spectrum/__init__.py +0 -1
- pvlib/spectrum/irradiance.py +2 -64
- pvlib/spectrum/mismatch.py +3 -3
- pvlib/tools.py +6 -5
- {pvlib-0.11.2.dist-info → pvlib-0.12.1a1.dist-info}/METADATA +6 -5
- pvlib-0.12.1a1.dist-info/RECORD +80 -0
- {pvlib-0.11.2.dist-info → pvlib-0.12.1a1.dist-info}/WHEEL +1 -1
- pvlib/data/BIRD_08_16_2012.csv +0 -8761
- pvlib/data/BIRD_08_16_2012_patm.csv +0 -8761
- pvlib/data/Burlington, United States SolarAnywhere Time Series 2021 Lat_44_465 Lon_-73_205 TMY3 format.csv +0 -8762
- pvlib/data/Burlington, United States SolarAnywhere Time Series 20210101 to 20210103 Lat_44_4675 Lon_-73_2075 SA format.csv +0 -578
- pvlib/data/Burlington, United States SolarAnywhere Typical GHI Year Lat_44_465 Lon_-73_205 SA format.csv +0 -74
- pvlib/data/CPS SCH275KTL-DO-US-800-250kW_275kVA_1.OND +0 -146
- pvlib/data/CRNS0101-05-2019-AZ_Tucson_11_W.txt +0 -4
- pvlib/data/CRN_with_problems.txt +0 -3
- pvlib/data/ET-M772BH550GL.PAN +0 -75
- pvlib/data/NLD_Amsterdam062400_IWEC.epw +0 -8768
- pvlib/data/PVsyst_demo.csv +0 -10757
- pvlib/data/PVsyst_demo_model.csv +0 -3588
- pvlib/data/SRML-day-EUPO1801.txt +0 -1441
- pvlib/data/abq19056.dat +0 -6
- pvlib/data/bishop88_numerical_precision.csv +0 -101
- pvlib/data/bsrn-lr0100-pay0616.dat +0 -86901
- pvlib/data/bsrn-pay0616.dat.gz +0 -0
- pvlib/data/cams_mcclear_1min_verbose.csv +0 -60
- pvlib/data/cams_mcclear_monthly.csv +0 -42
- pvlib/data/cams_radiation_1min_verbose.csv +0 -72
- pvlib/data/cams_radiation_monthly.csv +0 -47
- pvlib/data/detect_clearsky_data.csv +0 -35
- pvlib/data/detect_clearsky_threshold_data.csv +0 -126
- pvlib/data/greensboro_kimber_soil_manwash.dat +0 -8761
- pvlib/data/greensboro_kimber_soil_nowash.dat +0 -8761
- pvlib/data/inverter_fit_snl_meas.csv +0 -127
- pvlib/data/inverter_fit_snl_sim.csv +0 -19
- pvlib/data/ivtools_numdiff.csv +0 -52
- pvlib/data/midc_20181014.txt +0 -1441
- pvlib/data/midc_raw_20181018.txt +0 -1441
- pvlib/data/midc_raw_short_header_20191115.txt +0 -1441
- pvlib/data/msn19056.dat +0 -6
- pvlib/data/precise_iv_curves1.json +0 -10251
- pvlib/data/precise_iv_curves2.json +0 -10251
- pvlib/data/precise_iv_curves_parameter_sets1.csv +0 -33
- pvlib/data/precise_iv_curves_parameter_sets2.csv +0 -33
- pvlib/data/pvgis_hourly_Timeseries_45.000_8.000_SA2_10kWp_CIS_5_2a_2013_2014.json +0 -1
- pvlib/data/pvgis_hourly_Timeseries_45.000_8.000_SA_30deg_0deg_2016_2016.csv +0 -35
- pvlib/data/pvgis_tmy_meta.json +0 -32
- pvlib/data/pvgis_tmy_test.csv +0 -8761
- pvlib/data/pvwatts_8760_rackmount.csv +0 -8779
- pvlib/data/pvwatts_8760_roofmount.csv +0 -8779
- pvlib/data/singleaxis_tracker_wslope.csv +0 -8761
- pvlib/data/spectrl2_example_spectra.csv +0 -123
- pvlib/data/surfrad-slv16001.dat +0 -1442
- pvlib/data/test_psm3_2017.csv +0 -17521
- pvlib/data/test_psm3_2019_5min.csv +0 -289
- pvlib/data/test_psm3_tmy-2017.csv +0 -8761
- pvlib/data/test_read_psm3.csv +0 -17523
- pvlib/data/test_read_pvgis_horizon.csv +0 -49
- pvlib/data/tmy_45.000_8.000_2005_2023.csv +0 -8789
- pvlib/data/tmy_45.000_8.000_2005_2023.epw +0 -8768
- pvlib/data/tmy_45.000_8.000_2005_2023.json +0 -1
- pvlib/data/tmy_45.000_8.000_2005_2023.txt +0 -8761
- pvlib/data/tmy_45.000_8.000_userhorizon.json +0 -1
- pvlib/ivtools/sdm.py +0 -1379
- pvlib/spa_c_files/README.md +0 -81
- pvlib/spa_c_files/cspa_py.pxd +0 -43
- pvlib/spa_c_files/spa_py.pyx +0 -30
- pvlib/tests/__init__.py +0 -0
- pvlib/tests/bifacial/__init__.py +0 -0
- pvlib/tests/bifacial/test_infinite_sheds.py +0 -317
- pvlib/tests/bifacial/test_losses_models.py +0 -54
- pvlib/tests/bifacial/test_pvfactors.py +0 -82
- pvlib/tests/bifacial/test_utils.py +0 -192
- pvlib/tests/conftest.py +0 -476
- pvlib/tests/iotools/__init__.py +0 -0
- pvlib/tests/iotools/test_acis.py +0 -213
- pvlib/tests/iotools/test_bsrn.py +0 -131
- pvlib/tests/iotools/test_crn.py +0 -95
- pvlib/tests/iotools/test_epw.py +0 -23
- pvlib/tests/iotools/test_midc.py +0 -89
- pvlib/tests/iotools/test_panond.py +0 -32
- pvlib/tests/iotools/test_psm3.py +0 -198
- pvlib/tests/iotools/test_pvgis.py +0 -644
- pvlib/tests/iotools/test_sodapro.py +0 -298
- pvlib/tests/iotools/test_solaranywhere.py +0 -287
- pvlib/tests/iotools/test_solargis.py +0 -68
- pvlib/tests/iotools/test_solcast.py +0 -324
- pvlib/tests/iotools/test_solrad.py +0 -152
- pvlib/tests/iotools/test_srml.py +0 -124
- pvlib/tests/iotools/test_surfrad.py +0 -75
- pvlib/tests/iotools/test_tmy.py +0 -133
- pvlib/tests/ivtools/__init__.py +0 -0
- pvlib/tests/ivtools/test_sde.py +0 -230
- pvlib/tests/ivtools/test_sdm.py +0 -429
- pvlib/tests/ivtools/test_utils.py +0 -173
- pvlib/tests/spectrum/__init__.py +0 -0
- pvlib/tests/spectrum/conftest.py +0 -40
- pvlib/tests/spectrum/test_irradiance.py +0 -138
- pvlib/tests/spectrum/test_mismatch.py +0 -304
- pvlib/tests/spectrum/test_response.py +0 -124
- pvlib/tests/spectrum/test_spectrl2.py +0 -72
- pvlib/tests/test__deprecation.py +0 -97
- pvlib/tests/test_albedo.py +0 -84
- pvlib/tests/test_atmosphere.py +0 -351
- pvlib/tests/test_clearsky.py +0 -884
- pvlib/tests/test_conftest.py +0 -37
- pvlib/tests/test_iam.py +0 -555
- pvlib/tests/test_inverter.py +0 -213
- pvlib/tests/test_irradiance.py +0 -1487
- pvlib/tests/test_location.py +0 -356
- pvlib/tests/test_modelchain.py +0 -2020
- pvlib/tests/test_numerical_precision.py +0 -124
- pvlib/tests/test_pvarray.py +0 -71
- pvlib/tests/test_pvsystem.py +0 -2511
- pvlib/tests/test_scaling.py +0 -207
- pvlib/tests/test_shading.py +0 -391
- pvlib/tests/test_singlediode.py +0 -608
- pvlib/tests/test_snow.py +0 -212
- pvlib/tests/test_soiling.py +0 -230
- pvlib/tests/test_solarposition.py +0 -966
- pvlib/tests/test_spa.py +0 -454
- pvlib/tests/test_temperature.py +0 -470
- pvlib/tests/test_tools.py +0 -146
- pvlib/tests/test_tracking.py +0 -474
- pvlib/tests/test_transformer.py +0 -60
- pvlib-0.11.2.dist-info/RECORD +0 -191
- {pvlib-0.11.2.dist-info → pvlib-0.12.1a1.dist-info/licenses}/AUTHORS.md +0 -0
- {pvlib-0.11.2.dist-info → pvlib-0.12.1a1.dist-info/licenses}/LICENSE +0 -0
- {pvlib-0.11.2.dist-info → pvlib-0.12.1a1.dist-info}/top_level.txt +0 -0
pvlib/tests/test_singlediode.py
DELETED
|
@@ -1,608 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
testing single-diode methods using JW Bishop 1988
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
import numpy as np
|
|
6
|
-
import pandas as pd
|
|
7
|
-
import scipy
|
|
8
|
-
from pvlib import pvsystem
|
|
9
|
-
from pvlib.singlediode import (bishop88_mpp, estimate_voc, VOLTAGE_BUILTIN,
|
|
10
|
-
bishop88, bishop88_i_from_v, bishop88_v_from_i)
|
|
11
|
-
import pytest
|
|
12
|
-
from numpy.testing import assert_array_equal
|
|
13
|
-
from .conftest import DATA_DIR
|
|
14
|
-
|
|
15
|
-
POA = 888
|
|
16
|
-
TCELL = 55
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
@pytest.mark.parametrize('method', ['brentq', 'newton'])
|
|
20
|
-
def test_method_spr_e20_327(method, cec_module_spr_e20_327):
|
|
21
|
-
"""test pvsystem.singlediode with different methods on SPR-E20-327"""
|
|
22
|
-
spr_e20_327 = cec_module_spr_e20_327
|
|
23
|
-
x = pvsystem.calcparams_desoto(
|
|
24
|
-
effective_irradiance=POA, temp_cell=TCELL,
|
|
25
|
-
alpha_sc=spr_e20_327['alpha_sc'], a_ref=spr_e20_327['a_ref'],
|
|
26
|
-
I_L_ref=spr_e20_327['I_L_ref'], I_o_ref=spr_e20_327['I_o_ref'],
|
|
27
|
-
R_sh_ref=spr_e20_327['R_sh_ref'], R_s=spr_e20_327['R_s'],
|
|
28
|
-
EgRef=1.121, dEgdT=-0.0002677)
|
|
29
|
-
pvs = pvsystem.singlediode(*x, method='lambertw')
|
|
30
|
-
out = pvsystem.singlediode(*x, method=method)
|
|
31
|
-
|
|
32
|
-
assert np.isclose(pvs['i_sc'], out['i_sc'])
|
|
33
|
-
assert np.isclose(pvs['v_oc'], out['v_oc'])
|
|
34
|
-
assert np.isclose(pvs['i_mp'], out['i_mp'])
|
|
35
|
-
assert np.isclose(pvs['v_mp'], out['v_mp'])
|
|
36
|
-
assert np.isclose(pvs['p_mp'], out['p_mp'])
|
|
37
|
-
assert np.isclose(pvs['i_x'], out['i_x'])
|
|
38
|
-
assert np.isclose(pvs['i_xx'], out['i_xx'])
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
@pytest.mark.parametrize('method', ['brentq', 'newton'])
|
|
42
|
-
def test_newton_fs_495(method, cec_module_fs_495):
|
|
43
|
-
"""test pvsystem.singlediode with different methods on FS495"""
|
|
44
|
-
fs_495 = cec_module_fs_495
|
|
45
|
-
x = pvsystem.calcparams_desoto(
|
|
46
|
-
effective_irradiance=POA, temp_cell=TCELL,
|
|
47
|
-
alpha_sc=fs_495['alpha_sc'], a_ref=fs_495['a_ref'],
|
|
48
|
-
I_L_ref=fs_495['I_L_ref'], I_o_ref=fs_495['I_o_ref'],
|
|
49
|
-
R_sh_ref=fs_495['R_sh_ref'], R_s=fs_495['R_s'],
|
|
50
|
-
EgRef=1.475, dEgdT=-0.0003)
|
|
51
|
-
pvs = pvsystem.singlediode(*x, method='lambertw')
|
|
52
|
-
out = pvsystem.singlediode(*x, method=method)
|
|
53
|
-
|
|
54
|
-
assert np.isclose(pvs['i_sc'], out['i_sc'])
|
|
55
|
-
assert np.isclose(pvs['v_oc'], out['v_oc'])
|
|
56
|
-
assert np.isclose(pvs['i_mp'], out['i_mp'])
|
|
57
|
-
assert np.isclose(pvs['v_mp'], out['v_mp'])
|
|
58
|
-
assert np.isclose(pvs['p_mp'], out['p_mp'])
|
|
59
|
-
assert np.isclose(pvs['i_x'], out['i_x'])
|
|
60
|
-
assert np.isclose(pvs['i_xx'], out['i_xx'])
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
def build_precise_iv_curve_dataframe(file_csv, file_json):
|
|
64
|
-
"""
|
|
65
|
-
Reads a precise IV curve parameter set CSV and JSON to create a DataFrame.
|
|
66
|
-
The CSV contains the parameters of the single diode equation which are used
|
|
67
|
-
to generate the JSON data. The data are calculated using [1]_ with 40
|
|
68
|
-
decimal digits of precision in order have at least 16 decimal digits of
|
|
69
|
-
precision when they are stored in JSON. The precision is sufficient for the
|
|
70
|
-
difference between the left and right side of the single diode equation to
|
|
71
|
-
be less than :math:`1 \times 10^{-16}` when the numbers from the JSON are
|
|
72
|
-
read as mpmath floats. The code to generate these IV curve data is from
|
|
73
|
-
[2]_. The data and tests that use this function were added in :pull:`1573`.
|
|
74
|
-
|
|
75
|
-
Parameters
|
|
76
|
-
----------
|
|
77
|
-
file_csv: str
|
|
78
|
-
Path to a CSV file of IV curve parameter sets.
|
|
79
|
-
|
|
80
|
-
file_json: str
|
|
81
|
-
Path to a JSON file of precise IV curves.
|
|
82
|
-
|
|
83
|
-
Returns
|
|
84
|
-
-------
|
|
85
|
-
A DataFrame with these columns: ``Index``, ``photocurrent``,
|
|
86
|
-
``saturation_current``, ``resistance_series``, ``resistance_shunt``,
|
|
87
|
-
``n``, ``cells_in_series``, ``Voltages``, ``Currents``,
|
|
88
|
-
``diode_voltage``, ``v_oc``, ``i_sc``, ``v_mp``, ``i_mp``, ``p_mp``,
|
|
89
|
-
``i_x``, ``i_xx`, ``Temperature``, ``Irradiance``, ``Sweep Direction``,
|
|
90
|
-
``Datetime``, ``Boltzmann``, ``Elementary Charge``, and ``Vth``. The
|
|
91
|
-
columns ``Irradiance``, ``Sweep Direction`` are None or empty strings.
|
|
92
|
-
|
|
93
|
-
References
|
|
94
|
-
----------
|
|
95
|
-
.. [1] The mpmath development team. (2023). mpmath: a Python library for
|
|
96
|
-
arbitrary-precision floating-point arithmetic (version 1.2.1).
|
|
97
|
-
`mpmath <mpmath.org>`_
|
|
98
|
-
|
|
99
|
-
.. [2] The ivcurves development team. (2022). Code to generate precise
|
|
100
|
-
solutions to the single diode equation.
|
|
101
|
-
`ivcurves <github.com/cwhanse/ivcurves>`_
|
|
102
|
-
"""
|
|
103
|
-
params = pd.read_csv(file_csv)
|
|
104
|
-
curves_metadata = pd.read_json(file_json)
|
|
105
|
-
curves = pd.DataFrame(curves_metadata['IV Curves'].values.tolist())
|
|
106
|
-
curves['cells_in_series'] = curves_metadata['cells_in_series']
|
|
107
|
-
joined = params.merge(curves, on='Index', how='inner',
|
|
108
|
-
suffixes=(None, '_drop'), validate='one_to_one')
|
|
109
|
-
joined = joined[(c for c in joined.columns if not c.endswith('_drop'))]
|
|
110
|
-
|
|
111
|
-
# parse strings to np.float64
|
|
112
|
-
is_array = ['Currents', 'Voltages', 'diode_voltage']
|
|
113
|
-
for col in is_array:
|
|
114
|
-
joined[col] = [np.asarray(a, dtype=np.float64) for a in joined[col]]
|
|
115
|
-
is_number = ['v_oc', 'i_sc', 'v_mp', 'i_mp', 'p_mp', 'i_x', 'i_xx',
|
|
116
|
-
'Temperature']
|
|
117
|
-
joined[is_number] = joined[is_number].astype(np.float64)
|
|
118
|
-
|
|
119
|
-
joined['Boltzmann'] = scipy.constants.Boltzmann
|
|
120
|
-
joined['Elementary Charge'] = scipy.constants.elementary_charge
|
|
121
|
-
joined['Vth'] = (
|
|
122
|
-
joined['Boltzmann'] * joined['Temperature']
|
|
123
|
-
/ joined['Elementary Charge']
|
|
124
|
-
)
|
|
125
|
-
|
|
126
|
-
return joined
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
@pytest.fixture(scope='function', params=[
|
|
130
|
-
{
|
|
131
|
-
'csv': f'{DATA_DIR}/precise_iv_curves_parameter_sets1.csv',
|
|
132
|
-
'json': f'{DATA_DIR}/precise_iv_curves1.json'
|
|
133
|
-
},
|
|
134
|
-
{
|
|
135
|
-
'csv': f'{DATA_DIR}/precise_iv_curves_parameter_sets2.csv',
|
|
136
|
-
'json': f'{DATA_DIR}/precise_iv_curves2.json'
|
|
137
|
-
}
|
|
138
|
-
], ids=[1, 2])
|
|
139
|
-
def precise_iv_curves(request):
|
|
140
|
-
file_csv, file_json = request.param['csv'], request.param['json']
|
|
141
|
-
pc = build_precise_iv_curve_dataframe(file_csv, file_json)
|
|
142
|
-
params = ['photocurrent', 'saturation_current', 'resistance_series',
|
|
143
|
-
'resistance_shunt']
|
|
144
|
-
singlediode_params = pc.loc[:, params]
|
|
145
|
-
singlediode_params['nNsVth'] = pc['n'] * pc['cells_in_series'] * pc['Vth']
|
|
146
|
-
return singlediode_params, pc
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
@pytest.mark.parametrize('method', ['lambertw', 'brentq', 'newton'])
|
|
150
|
-
def test_singlediode_precision(method, precise_iv_curves):
|
|
151
|
-
"""
|
|
152
|
-
Tests the accuracy of singlediode. ivcurve_pnts is not tested.
|
|
153
|
-
"""
|
|
154
|
-
x, pc = precise_iv_curves
|
|
155
|
-
outs = pvsystem.singlediode(method=method, **x)
|
|
156
|
-
|
|
157
|
-
assert np.allclose(pc['i_sc'], outs['i_sc'], atol=1e-10, rtol=0)
|
|
158
|
-
assert np.allclose(pc['v_oc'], outs['v_oc'], atol=1e-10, rtol=0)
|
|
159
|
-
assert np.allclose(pc['i_mp'], outs['i_mp'], atol=7e-8, rtol=0)
|
|
160
|
-
assert np.allclose(pc['v_mp'], outs['v_mp'], atol=1e-6, rtol=0)
|
|
161
|
-
assert np.allclose(pc['p_mp'], outs['p_mp'], atol=1e-10, rtol=0)
|
|
162
|
-
assert np.allclose(pc['i_x'], outs['i_x'], atol=1e-10, rtol=0)
|
|
163
|
-
|
|
164
|
-
# This test should pass with atol=9e-8 on MacOS and Windows.
|
|
165
|
-
# The atol was lowered to pass on Linux when the vectorized umath module
|
|
166
|
-
# introduced in NumPy 1.22.0 is used.
|
|
167
|
-
assert np.allclose(pc['i_xx'], outs['i_xx'], atol=1e-6, rtol=0)
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
def test_singlediode_lambert_negative_voc(mocker):
|
|
171
|
-
"""Tests approximation to zero of v_oc when it is negative and small.
|
|
172
|
-
See singlediode.py:_lambertw > comment 'Set small elements <0 in v_oc to 0'
|
|
173
|
-
"""
|
|
174
|
-
# Next values should result in a negative v_oc out of `_lambertw_v_from_i`
|
|
175
|
-
# however, we can't ensure that the output belongs to (-1e-12, 0), so we
|
|
176
|
-
# mock it. It depends on the platform and Python distro. See issue #2000.
|
|
177
|
-
patcher = mocker.patch("pvlib.singlediode._lambertw_v_from_i")
|
|
178
|
-
x = np.array([0.0, 1.480501e-11, 0.178, 8000.0, 1.797559])
|
|
179
|
-
patcher.return_value = -9.999e-13
|
|
180
|
-
outs = pvsystem.singlediode(*x, method="lambertw")
|
|
181
|
-
assert outs["v_oc"] == 0
|
|
182
|
-
|
|
183
|
-
# Testing for an array
|
|
184
|
-
patcher.return_value = np.array([-9.999e-13, -1.001e-13])
|
|
185
|
-
x = np.array([x, x]).T
|
|
186
|
-
outs = pvsystem.singlediode(*x, method="lambertw")
|
|
187
|
-
assert_array_equal(outs["v_oc"], [0, 0])
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
@pytest.mark.parametrize('method', ['lambertw', 'brentq', 'newton'])
|
|
191
|
-
def test_v_from_i_i_from_v_precision(method, precise_iv_curves):
|
|
192
|
-
"""
|
|
193
|
-
Tests the accuracy of pvsystem.v_from_i and pvsystem.i_from_v.
|
|
194
|
-
"""
|
|
195
|
-
x, pc = precise_iv_curves
|
|
196
|
-
pc_i, pc_v = pc['Currents'], pc['Voltages']
|
|
197
|
-
for i, v, (_, x_one_curve) in zip(pc_i, pc_v, x.iterrows()):
|
|
198
|
-
out_i = pvsystem.i_from_v(voltage=v, method=method, **x_one_curve)
|
|
199
|
-
out_v = pvsystem.v_from_i(current=i, method=method, **x_one_curve)
|
|
200
|
-
|
|
201
|
-
assert np.allclose(i, out_i, atol=1e-10, rtol=0)
|
|
202
|
-
assert np.allclose(v, out_v, atol=1e-10, rtol=0)
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
def get_pvsyst_fs_495():
|
|
206
|
-
"""
|
|
207
|
-
PVsyst parameters for First Solar FS-495 module from PVSyst-6.7.2 database.
|
|
208
|
-
|
|
209
|
-
I_L_ref derived from Isc_ref conditions::
|
|
210
|
-
|
|
211
|
-
I_L_ref = (I_sc_ref + Id + Ish) / (1 - d2mutau/(Vbi*N_s - Vd))
|
|
212
|
-
|
|
213
|
-
where::
|
|
214
|
-
|
|
215
|
-
Vd = I_sc_ref * R_s
|
|
216
|
-
Id = I_o_ref * (exp(Vd / nNsVt) - 1)
|
|
217
|
-
Ish = Vd / R_sh_ref
|
|
218
|
-
|
|
219
|
-
"""
|
|
220
|
-
return {
|
|
221
|
-
'd2mutau': 1.31, 'alpha_sc': 0.00039, 'gamma_ref': 1.48,
|
|
222
|
-
'mu_gamma': 0.001, 'I_o_ref': 9.62e-10, 'R_sh_ref': 5000,
|
|
223
|
-
'R_sh_0': 12500, 'R_sh_exp': 3.1, 'R_s': 4.6, 'beta_oc': -0.2116,
|
|
224
|
-
'EgRef': 1.5, 'cells_in_series': 108, 'cells_in_parallel': 2,
|
|
225
|
-
'I_sc_ref': 1.55, 'V_oc_ref': 86.5, 'I_mp_ref': 1.4, 'V_mp_ref': 67.85,
|
|
226
|
-
'temp_ref': 25, 'irrad_ref': 1000, 'I_L_ref': 1.5743233463848496
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
# DeSoto @(888[W/m**2], 55[degC]) = {Pmp: 72.71, Isc: 1.402, Voc: 75.42)
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
@pytest.mark.parametrize(
|
|
233
|
-
'poa, temp_cell, expected, tol', [
|
|
234
|
-
# reference conditions
|
|
235
|
-
(
|
|
236
|
-
get_pvsyst_fs_495()['irrad_ref'],
|
|
237
|
-
get_pvsyst_fs_495()['temp_ref'],
|
|
238
|
-
{
|
|
239
|
-
'pmp': (get_pvsyst_fs_495()['I_mp_ref'] *
|
|
240
|
-
get_pvsyst_fs_495()['V_mp_ref']),
|
|
241
|
-
'isc': get_pvsyst_fs_495()['I_sc_ref'],
|
|
242
|
-
'voc': get_pvsyst_fs_495()['V_oc_ref']
|
|
243
|
-
},
|
|
244
|
-
(5e-4, 0.04)
|
|
245
|
-
),
|
|
246
|
-
# other conditions
|
|
247
|
-
(
|
|
248
|
-
POA,
|
|
249
|
-
TCELL,
|
|
250
|
-
{
|
|
251
|
-
'pmp': 76.262,
|
|
252
|
-
'isc': 1.3868,
|
|
253
|
-
'voc': 79.292
|
|
254
|
-
},
|
|
255
|
-
(1e-4, 1e-4)
|
|
256
|
-
)
|
|
257
|
-
]
|
|
258
|
-
)
|
|
259
|
-
@pytest.mark.parametrize('method', ['newton', 'brentq'])
|
|
260
|
-
def test_pvsyst_recombination_loss(method, poa, temp_cell, expected, tol):
|
|
261
|
-
"""test PVSst recombination loss"""
|
|
262
|
-
pvsyst_fs_495 = get_pvsyst_fs_495()
|
|
263
|
-
# first evaluate PVSyst model with thin-film recombination loss current
|
|
264
|
-
# at reference conditions
|
|
265
|
-
x = pvsystem.calcparams_pvsyst(
|
|
266
|
-
effective_irradiance=poa, temp_cell=temp_cell,
|
|
267
|
-
alpha_sc=pvsyst_fs_495['alpha_sc'],
|
|
268
|
-
gamma_ref=pvsyst_fs_495['gamma_ref'],
|
|
269
|
-
mu_gamma=pvsyst_fs_495['mu_gamma'], I_L_ref=pvsyst_fs_495['I_L_ref'],
|
|
270
|
-
I_o_ref=pvsyst_fs_495['I_o_ref'], R_sh_ref=pvsyst_fs_495['R_sh_ref'],
|
|
271
|
-
R_sh_0=pvsyst_fs_495['R_sh_0'], R_sh_exp=pvsyst_fs_495['R_sh_exp'],
|
|
272
|
-
R_s=pvsyst_fs_495['R_s'],
|
|
273
|
-
cells_in_series=pvsyst_fs_495['cells_in_series'],
|
|
274
|
-
EgRef=pvsyst_fs_495['EgRef']
|
|
275
|
-
)
|
|
276
|
-
il_pvsyst, io_pvsyst, rs_pvsyst, rsh_pvsyst, nnsvt_pvsyst = x
|
|
277
|
-
voc_est_pvsyst = estimate_voc(photocurrent=il_pvsyst,
|
|
278
|
-
saturation_current=io_pvsyst,
|
|
279
|
-
nNsVth=nnsvt_pvsyst)
|
|
280
|
-
vd_pvsyst = np.linspace(0, voc_est_pvsyst, 1000)
|
|
281
|
-
pvsyst = bishop88(
|
|
282
|
-
diode_voltage=vd_pvsyst, photocurrent=il_pvsyst,
|
|
283
|
-
saturation_current=io_pvsyst, resistance_series=rs_pvsyst,
|
|
284
|
-
resistance_shunt=rsh_pvsyst, nNsVth=nnsvt_pvsyst,
|
|
285
|
-
d2mutau=pvsyst_fs_495['d2mutau'],
|
|
286
|
-
NsVbi=VOLTAGE_BUILTIN*pvsyst_fs_495['cells_in_series']
|
|
287
|
-
)
|
|
288
|
-
# test max power
|
|
289
|
-
assert np.isclose(max(pvsyst[2]), expected['pmp'], *tol)
|
|
290
|
-
|
|
291
|
-
# test short circuit current
|
|
292
|
-
isc_pvsyst = np.interp(0, pvsyst[1], pvsyst[0])
|
|
293
|
-
assert np.isclose(isc_pvsyst, expected['isc'], *tol)
|
|
294
|
-
|
|
295
|
-
# test open circuit voltage
|
|
296
|
-
voc_pvsyst = np.interp(0, pvsyst[0][::-1], pvsyst[1][::-1])
|
|
297
|
-
assert np.isclose(voc_pvsyst, expected['voc'], *tol)
|
|
298
|
-
|
|
299
|
-
# repeat tests as above with specialized bishop88 functions
|
|
300
|
-
y = dict(d2mutau=pvsyst_fs_495['d2mutau'],
|
|
301
|
-
NsVbi=VOLTAGE_BUILTIN*pvsyst_fs_495['cells_in_series'])
|
|
302
|
-
|
|
303
|
-
mpp_88 = bishop88_mpp(*x, **y, method=method)
|
|
304
|
-
assert np.isclose(mpp_88[2], expected['pmp'], *tol)
|
|
305
|
-
|
|
306
|
-
isc_88 = bishop88_i_from_v(0, *x, **y, method=method)
|
|
307
|
-
assert np.isclose(isc_88, expected['isc'], *tol)
|
|
308
|
-
|
|
309
|
-
voc_88 = bishop88_v_from_i(0, *x, **y, method=method)
|
|
310
|
-
assert np.isclose(voc_88, expected['voc'], *tol)
|
|
311
|
-
|
|
312
|
-
ioc_88 = bishop88_i_from_v(voc_88, *x, **y, method=method)
|
|
313
|
-
assert np.isclose(ioc_88, 0.0, *tol)
|
|
314
|
-
|
|
315
|
-
vsc_88 = bishop88_v_from_i(isc_88, *x, **y, method=method)
|
|
316
|
-
assert np.isclose(vsc_88, 0.0, *tol)
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
@pytest.mark.parametrize(
|
|
320
|
-
'brk_params, recomb_params, poa, temp_cell, expected, tol', [
|
|
321
|
-
# reference conditions without breakdown model
|
|
322
|
-
(
|
|
323
|
-
(0., -5.5, 3.28),
|
|
324
|
-
(get_pvsyst_fs_495()['d2mutau'],
|
|
325
|
-
VOLTAGE_BUILTIN * get_pvsyst_fs_495()['cells_in_series']),
|
|
326
|
-
get_pvsyst_fs_495()['irrad_ref'],
|
|
327
|
-
get_pvsyst_fs_495()['temp_ref'],
|
|
328
|
-
{
|
|
329
|
-
'pmp': (get_pvsyst_fs_495()['I_mp_ref'] * # noqa: W504
|
|
330
|
-
get_pvsyst_fs_495()['V_mp_ref']),
|
|
331
|
-
'isc': get_pvsyst_fs_495()['I_sc_ref'],
|
|
332
|
-
'voc': get_pvsyst_fs_495()['V_oc_ref']
|
|
333
|
-
},
|
|
334
|
-
(5e-4, 0.04)
|
|
335
|
-
),
|
|
336
|
-
# other conditions with breakdown model on and recombination model off
|
|
337
|
-
(
|
|
338
|
-
(1.e-4, -5.5, 3.28),
|
|
339
|
-
(0., np.inf),
|
|
340
|
-
POA,
|
|
341
|
-
TCELL,
|
|
342
|
-
{
|
|
343
|
-
'pmp': 79.723,
|
|
344
|
-
'isc': 1.4071,
|
|
345
|
-
'voc': 79.646
|
|
346
|
-
},
|
|
347
|
-
(1e-4, 1e-4)
|
|
348
|
-
)
|
|
349
|
-
]
|
|
350
|
-
)
|
|
351
|
-
@pytest.mark.parametrize('method', ['newton', 'brentq'])
|
|
352
|
-
def test_pvsyst_breakdown(method, brk_params, recomb_params, poa, temp_cell,
|
|
353
|
-
expected, tol):
|
|
354
|
-
"""test PVSyst recombination loss"""
|
|
355
|
-
pvsyst_fs_495 = get_pvsyst_fs_495()
|
|
356
|
-
# first evaluate PVSyst model with thin-film recombination loss current
|
|
357
|
-
# at reference conditions
|
|
358
|
-
x = pvsystem.calcparams_pvsyst(
|
|
359
|
-
effective_irradiance=poa, temp_cell=temp_cell,
|
|
360
|
-
alpha_sc=pvsyst_fs_495['alpha_sc'],
|
|
361
|
-
gamma_ref=pvsyst_fs_495['gamma_ref'],
|
|
362
|
-
mu_gamma=pvsyst_fs_495['mu_gamma'], I_L_ref=pvsyst_fs_495['I_L_ref'],
|
|
363
|
-
I_o_ref=pvsyst_fs_495['I_o_ref'], R_sh_ref=pvsyst_fs_495['R_sh_ref'],
|
|
364
|
-
R_sh_0=pvsyst_fs_495['R_sh_0'], R_sh_exp=pvsyst_fs_495['R_sh_exp'],
|
|
365
|
-
R_s=pvsyst_fs_495['R_s'],
|
|
366
|
-
cells_in_series=pvsyst_fs_495['cells_in_series'],
|
|
367
|
-
EgRef=pvsyst_fs_495['EgRef']
|
|
368
|
-
)
|
|
369
|
-
il_pvsyst, io_pvsyst, rs_pvsyst, rsh_pvsyst, nnsvt_pvsyst = x
|
|
370
|
-
|
|
371
|
-
d2mutau, NsVbi = recomb_params
|
|
372
|
-
breakdown_factor, breakdown_voltage, breakdown_exp = brk_params
|
|
373
|
-
|
|
374
|
-
voc_est_pvsyst = estimate_voc(photocurrent=il_pvsyst,
|
|
375
|
-
saturation_current=io_pvsyst,
|
|
376
|
-
nNsVth=nnsvt_pvsyst)
|
|
377
|
-
vd_pvsyst = np.linspace(0, voc_est_pvsyst, 1000)
|
|
378
|
-
pvsyst = bishop88(
|
|
379
|
-
diode_voltage=vd_pvsyst, photocurrent=il_pvsyst,
|
|
380
|
-
saturation_current=io_pvsyst, resistance_series=rs_pvsyst,
|
|
381
|
-
resistance_shunt=rsh_pvsyst, nNsVth=nnsvt_pvsyst,
|
|
382
|
-
d2mutau=d2mutau, NsVbi=NsVbi,
|
|
383
|
-
breakdown_factor=breakdown_factor, breakdown_voltage=breakdown_voltage,
|
|
384
|
-
breakdown_exp=breakdown_exp
|
|
385
|
-
)
|
|
386
|
-
# test max power
|
|
387
|
-
assert np.isclose(max(pvsyst[2]), expected['pmp'], *tol)
|
|
388
|
-
|
|
389
|
-
# test short circuit current
|
|
390
|
-
isc_pvsyst = np.interp(0, pvsyst[1], pvsyst[0])
|
|
391
|
-
assert np.isclose(isc_pvsyst, expected['isc'], *tol)
|
|
392
|
-
|
|
393
|
-
# test open circuit voltage
|
|
394
|
-
voc_pvsyst = np.interp(0, pvsyst[0][::-1], pvsyst[1][::-1])
|
|
395
|
-
assert np.isclose(voc_pvsyst, expected['voc'], *tol)
|
|
396
|
-
|
|
397
|
-
# repeat tests as above with specialized bishop88 functions
|
|
398
|
-
y = {'d2mutau': recomb_params[0], 'NsVbi': recomb_params[1],
|
|
399
|
-
'breakdown_factor': brk_params[0], 'breakdown_voltage': brk_params[1],
|
|
400
|
-
'breakdown_exp': brk_params[2]}
|
|
401
|
-
|
|
402
|
-
mpp_88 = bishop88_mpp(*x, **y, method=method)
|
|
403
|
-
assert np.isclose(mpp_88[2], expected['pmp'], *tol)
|
|
404
|
-
|
|
405
|
-
isc_88 = bishop88_i_from_v(0, *x, **y, method=method)
|
|
406
|
-
assert np.isclose(isc_88, expected['isc'], *tol)
|
|
407
|
-
|
|
408
|
-
voc_88 = bishop88_v_from_i(0, *x, **y, method=method)
|
|
409
|
-
assert np.isclose(voc_88, expected['voc'], *tol)
|
|
410
|
-
|
|
411
|
-
ioc_88 = bishop88_i_from_v(voc_88, *x, **y, method=method)
|
|
412
|
-
assert np.isclose(ioc_88, 0.0, *tol)
|
|
413
|
-
|
|
414
|
-
vsc_88 = bishop88_v_from_i(isc_88, *x, **y, method=method)
|
|
415
|
-
assert np.isclose(vsc_88, 0.0, *tol)
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
@pytest.fixture
|
|
419
|
-
def bishop88_arguments():
|
|
420
|
-
pvsyst_fs_495 = get_pvsyst_fs_495()
|
|
421
|
-
# evaluate PVSyst model with thin-film recombination loss current
|
|
422
|
-
# at reference conditions
|
|
423
|
-
x = pvsystem.calcparams_pvsyst(
|
|
424
|
-
effective_irradiance=pvsyst_fs_495['irrad_ref'],
|
|
425
|
-
temp_cell=pvsyst_fs_495['temp_ref'],
|
|
426
|
-
alpha_sc=pvsyst_fs_495['alpha_sc'],
|
|
427
|
-
gamma_ref=pvsyst_fs_495['gamma_ref'],
|
|
428
|
-
mu_gamma=pvsyst_fs_495['mu_gamma'], I_L_ref=pvsyst_fs_495['I_L_ref'],
|
|
429
|
-
I_o_ref=pvsyst_fs_495['I_o_ref'], R_sh_ref=pvsyst_fs_495['R_sh_ref'],
|
|
430
|
-
R_sh_0=pvsyst_fs_495['R_sh_0'], R_sh_exp=pvsyst_fs_495['R_sh_exp'],
|
|
431
|
-
R_s=pvsyst_fs_495['R_s'],
|
|
432
|
-
cells_in_series=pvsyst_fs_495['cells_in_series'],
|
|
433
|
-
EgRef=pvsyst_fs_495['EgRef']
|
|
434
|
-
)
|
|
435
|
-
y = dict(d2mutau=pvsyst_fs_495['d2mutau'],
|
|
436
|
-
NsVbi=VOLTAGE_BUILTIN*pvsyst_fs_495['cells_in_series'])
|
|
437
|
-
# Convert (*x, **y) in a bishop88_.* call to dict of arguments
|
|
438
|
-
args_dict = {
|
|
439
|
-
'photocurrent': x[0],
|
|
440
|
-
'saturation_current': x[1],
|
|
441
|
-
'resistance_series': x[2],
|
|
442
|
-
'resistance_shunt': x[3],
|
|
443
|
-
'nNsVth': x[4],
|
|
444
|
-
}
|
|
445
|
-
args_dict.update(y)
|
|
446
|
-
return args_dict
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
@pytest.mark.parametrize('method, method_kwargs', [
|
|
450
|
-
('newton', {
|
|
451
|
-
'tol': 1e-8,
|
|
452
|
-
'rtol': 1e-8,
|
|
453
|
-
'maxiter': 30,
|
|
454
|
-
}),
|
|
455
|
-
('brentq', {
|
|
456
|
-
'xtol': 1e-8,
|
|
457
|
-
'rtol': 1e-8,
|
|
458
|
-
'maxiter': 30,
|
|
459
|
-
})
|
|
460
|
-
])
|
|
461
|
-
def test_bishop88_kwargs_transfer(method, method_kwargs, mocker,
|
|
462
|
-
bishop88_arguments):
|
|
463
|
-
"""test method_kwargs modifying optimizer does not break anything"""
|
|
464
|
-
# patch method namespace at singlediode module namespace
|
|
465
|
-
optimizer_mock = mocker.patch('pvlib.singlediode.' + method)
|
|
466
|
-
|
|
467
|
-
# check kwargs passed to bishop_.* are a subset of the call args
|
|
468
|
-
# since they are called with more keyword arguments
|
|
469
|
-
|
|
470
|
-
bishop88_i_from_v(0, **bishop88_arguments, method=method,
|
|
471
|
-
method_kwargs=method_kwargs)
|
|
472
|
-
_, kwargs = optimizer_mock.call_args
|
|
473
|
-
assert method_kwargs.items() <= kwargs.items()
|
|
474
|
-
|
|
475
|
-
bishop88_v_from_i(0, **bishop88_arguments, method=method,
|
|
476
|
-
method_kwargs=method_kwargs)
|
|
477
|
-
_, kwargs = optimizer_mock.call_args
|
|
478
|
-
assert method_kwargs.items() <= kwargs.items()
|
|
479
|
-
|
|
480
|
-
bishop88_mpp(**bishop88_arguments, method=method,
|
|
481
|
-
method_kwargs=method_kwargs)
|
|
482
|
-
_, kwargs = optimizer_mock.call_args
|
|
483
|
-
assert method_kwargs.items() <= kwargs.items()
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
@pytest.mark.parametrize('method, method_kwargs', [
|
|
487
|
-
('newton', {
|
|
488
|
-
'tol': 1e-4,
|
|
489
|
-
'rtol': 1e-4,
|
|
490
|
-
'maxiter': 20,
|
|
491
|
-
'_inexistent_param': "0.01"
|
|
492
|
-
}),
|
|
493
|
-
('brentq', {
|
|
494
|
-
'xtol': 1e-4,
|
|
495
|
-
'rtol': 1e-4,
|
|
496
|
-
'maxiter': 20,
|
|
497
|
-
'_inexistent_param': "0.01"
|
|
498
|
-
})
|
|
499
|
-
])
|
|
500
|
-
def test_bishop88_kwargs_fails(method, method_kwargs, bishop88_arguments):
|
|
501
|
-
"""test invalid method_kwargs passed onto the optimizer fail"""
|
|
502
|
-
|
|
503
|
-
pytest.raises(TypeError, bishop88_i_from_v,
|
|
504
|
-
0, **bishop88_arguments, method=method,
|
|
505
|
-
method_kwargs=method_kwargs)
|
|
506
|
-
|
|
507
|
-
pytest.raises(TypeError, bishop88_v_from_i,
|
|
508
|
-
0, **bishop88_arguments, method=method,
|
|
509
|
-
method_kwargs=method_kwargs)
|
|
510
|
-
|
|
511
|
-
pytest.raises(TypeError, bishop88_mpp,
|
|
512
|
-
**bishop88_arguments, method=method,
|
|
513
|
-
method_kwargs=method_kwargs)
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
@pytest.mark.parametrize('method', ['newton', 'brentq'])
|
|
517
|
-
def test_bishop88_full_output_kwarg(method, bishop88_arguments):
|
|
518
|
-
"""test call to bishop88_.* with full_output=True return values are ok"""
|
|
519
|
-
method_kwargs = {'full_output': True}
|
|
520
|
-
|
|
521
|
-
ret_val = bishop88_i_from_v(0, **bishop88_arguments, method=method,
|
|
522
|
-
method_kwargs=method_kwargs)
|
|
523
|
-
assert isinstance(ret_val, tuple) # ret_val must be a tuple
|
|
524
|
-
assert len(ret_val) == 2 # of two elements
|
|
525
|
-
assert isinstance(ret_val[0], float) # first one has bishop88 result
|
|
526
|
-
assert isinstance(ret_val[1], tuple) # second is output from optimizer
|
|
527
|
-
# any root finder returns at least 2 elements with full_output=True
|
|
528
|
-
assert len(ret_val[1]) >= 2
|
|
529
|
-
|
|
530
|
-
ret_val = bishop88_v_from_i(0, **bishop88_arguments, method=method,
|
|
531
|
-
method_kwargs=method_kwargs)
|
|
532
|
-
assert isinstance(ret_val, tuple) # ret_val must be a tuple
|
|
533
|
-
assert len(ret_val) == 2 # of two elements
|
|
534
|
-
assert isinstance(ret_val[0], float) # first one has bishop88 result
|
|
535
|
-
assert isinstance(ret_val[1], tuple) # second is output from optimizer
|
|
536
|
-
# any root finder returns at least 2 elements with full_output=True
|
|
537
|
-
assert len(ret_val[1]) >= 2
|
|
538
|
-
|
|
539
|
-
ret_val = bishop88_mpp(**bishop88_arguments, method=method,
|
|
540
|
-
method_kwargs=method_kwargs)
|
|
541
|
-
assert isinstance(ret_val, tuple) # ret_val must be a tuple
|
|
542
|
-
assert len(ret_val) == 2 # of two elements
|
|
543
|
-
assert isinstance(ret_val[0], tuple) # first one has bishop88 result
|
|
544
|
-
assert len(ret_val[0]) == 3 # of three elements (I,V,P)
|
|
545
|
-
assert isinstance(ret_val[1], tuple) # second is output from optimizer
|
|
546
|
-
# any root finder returns at least 2 elements with full_output=True
|
|
547
|
-
assert len(ret_val[1]) >= 2
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
@pytest.mark.parametrize('method', ['newton', 'brentq'])
|
|
551
|
-
def test_bishop88_pdSeries_len_one(method, bishop88_arguments):
|
|
552
|
-
for k, v in bishop88_arguments.items():
|
|
553
|
-
bishop88_arguments[k] = pd.Series([v])
|
|
554
|
-
|
|
555
|
-
# should not raise error
|
|
556
|
-
bishop88_i_from_v(pd.Series([0]), **bishop88_arguments, method=method)
|
|
557
|
-
bishop88_v_from_i(pd.Series([0]), **bishop88_arguments, method=method)
|
|
558
|
-
bishop88_mpp(**bishop88_arguments, method=method)
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
def _sde_check_solution(i, v, il, io, rs, rsh, a, d2mutau=0., NsVbi=np.inf):
|
|
562
|
-
vd = v + rs * i
|
|
563
|
-
return il - io*np.expm1(vd/a) - vd/rsh - il*d2mutau/(NsVbi - vd) - i
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
@pytest.mark.parametrize('method', ['newton', 'brentq'])
|
|
567
|
-
def test_bishop88_init_cond(method):
|
|
568
|
-
# GH 2013
|
|
569
|
-
p = {'alpha_sc': 0.0012256,
|
|
570
|
-
'gamma_ref': 1.2916241612804187,
|
|
571
|
-
'mu_gamma': 0.00047308959960937403,
|
|
572
|
-
'I_L_ref': 3.068717040806731,
|
|
573
|
-
'I_o_ref': 2.2691248021217617e-11,
|
|
574
|
-
'R_sh_ref': 7000,
|
|
575
|
-
'R_sh_0': 7000,
|
|
576
|
-
'R_s': 4.602,
|
|
577
|
-
'cells_in_series': 268,
|
|
578
|
-
'R_sh_exp': 5.5,
|
|
579
|
-
'EgRef': 1.5}
|
|
580
|
-
NsVbi = 268 * 0.9
|
|
581
|
-
d2mutau = 1.4
|
|
582
|
-
irrad = np.arange(20, 1100, 20)
|
|
583
|
-
tc = np.arange(-25, 74, 1)
|
|
584
|
-
weather = np.array(np.meshgrid(irrad, tc)).T.reshape(-1, 2)
|
|
585
|
-
# with the above parameters and weather conditions, a few combinations
|
|
586
|
-
# result in voc_est > NsVbi, which causes failure of brentq and newton
|
|
587
|
-
# when the recombination parameters NsVbi and d2mutau are used.
|
|
588
|
-
sde_params = pvsystem.calcparams_pvsyst(weather[:, 0], weather[:, 1], **p)
|
|
589
|
-
# test _mpp
|
|
590
|
-
result = bishop88_mpp(*sde_params, d2mutau=d2mutau, NsVbi=NsVbi)
|
|
591
|
-
imp, vmp, pmp = result
|
|
592
|
-
err = np.abs(_sde_check_solution(
|
|
593
|
-
imp, vmp, sde_params[0], sde_params[1], sde_params[2], sde_params[3],
|
|
594
|
-
sde_params[4], d2mutau=d2mutau, NsVbi=NsVbi))
|
|
595
|
-
bad_results = np.isnan(pmp) | (pmp < 0) | (err > 0.00001) # 0.01mA error
|
|
596
|
-
assert not bad_results.any()
|
|
597
|
-
# test v_from_i
|
|
598
|
-
vmp2 = bishop88_v_from_i(imp, *sde_params, d2mutau=d2mutau, NsVbi=NsVbi)
|
|
599
|
-
err = np.abs(_sde_check_solution(imp, vmp2, *sde_params, d2mutau=d2mutau,
|
|
600
|
-
NsVbi=NsVbi))
|
|
601
|
-
bad_results = np.isnan(vmp2) | (vmp2 < 0) | (err > 0.00001)
|
|
602
|
-
assert not bad_results.any()
|
|
603
|
-
# test v_from_i
|
|
604
|
-
imp2 = bishop88_i_from_v(vmp, *sde_params, d2mutau=d2mutau, NsVbi=NsVbi)
|
|
605
|
-
err = np.abs(_sde_check_solution(imp2, vmp, *sde_params, d2mutau=d2mutau,
|
|
606
|
-
NsVbi=NsVbi))
|
|
607
|
-
bad_results = np.isnan(imp2) | (imp2 < 0) | (err > 0.00001)
|
|
608
|
-
assert not bad_results.any()
|