|
7 | 7 | import scipy |
8 | 8 | from pvlib import pvsystem |
9 | 9 | from pvlib.singlediode import (bishop88_mpp, estimate_voc, VOLTAGE_BUILTIN, |
10 | | - bishop88, bishop88_i_from_v, bishop88_v_from_i) |
| 10 | + bishop88, bishop88_i_from_v, bishop88_v_from_i, |
| 11 | + batzelis_keypoints) |
11 | 12 | import pytest |
12 | 13 | from numpy.testing import assert_array_equal |
13 | 14 | from .conftest import TESTS_DATA_DIR |
@@ -600,9 +601,52 @@ def test_bishop88_init_cond(method): |
600 | 601 | NsVbi=NsVbi)) |
601 | 602 | bad_results = np.isnan(vmp2) | (vmp2 < 0) | (err > 0.00001) |
602 | 603 | assert not bad_results.any() |
603 | | - # test v_from_i |
| 604 | + # test i_from_v |
604 | 605 | imp2 = bishop88_i_from_v(vmp, *sde_params, d2mutau=d2mutau, NsVbi=NsVbi) |
605 | 606 | err = np.abs(_sde_check_solution(imp2, vmp, *sde_params, d2mutau=d2mutau, |
606 | 607 | NsVbi=NsVbi)) |
607 | 608 | bad_results = np.isnan(imp2) | (imp2 < 0) | (err > 0.00001) |
608 | 609 | assert not bad_results.any() |
| 610 | + |
| 611 | + |
| 612 | +def test_batzelis_keypoints(): |
| 613 | + params = {'photocurrent': 10, 'saturation_current': 1e-10, |
| 614 | + 'resistance_series': 0.2, 'resistance_shunt': 3000, |
| 615 | + 'nNsVth': 1.7} |
| 616 | + |
| 617 | + exact_values = { # calculated using pvlib.pvsystem.singlediode |
| 618 | + 'i_sc': 9.999333377550565, |
| 619 | + 'v_oc': 43.05589965219406, |
| 620 | + 'i_mp': 9.513255314772051, |
| 621 | + 'v_mp': 35.97259289596944, |
| 622 | + 'p_mp': 342.21646055371264, |
| 623 | + } |
| 624 | + rtol = 5e-3 # accurate to within half a percent in this case |
| 625 | + |
| 626 | + output = batzelis_keypoints(**params) |
| 627 | + for key in exact_values: |
| 628 | + assert output[key] == pytest.approx(exact_values[key], rel=rtol) |
| 629 | + |
| 630 | + # numpy arrays |
| 631 | + params2 = {k: np.array([v] * 2) for k, v in params.items()} |
| 632 | + output2 = batzelis_keypoints(**params2) |
| 633 | + for key in exact_values: |
| 634 | + exp = np.array([exact_values[key]] * 2) |
| 635 | + np.testing.assert_allclose(output2[key], exp, rtol=rtol) |
| 636 | + |
| 637 | + # pandas |
| 638 | + params3 = {k: pd.Series(v) for k, v in params2.items()} |
| 639 | + output3 = batzelis_keypoints(**params3) |
| 640 | + assert isinstance(output3, pd.DataFrame) |
| 641 | + for key in exact_values: |
| 642 | + exp = pd.Series([exact_values[key]] * 2) |
| 643 | + np.testing.assert_allclose(output3[key], exp, rtol=rtol) |
| 644 | + |
| 645 | + |
| 646 | +def test_batzelis_keypoints_night(): |
| 647 | + # SDMs produce photocurrent=0 and resistance_shunt=inf at night |
| 648 | + out = batzelis_keypoints(photocurrent=0, saturation_current=1e-10, |
| 649 | + resistance_series=0.2, resistance_shunt=np.inf, |
| 650 | + nNsVth=1.7) |
| 651 | + for k, v in out.items(): |
| 652 | + assert v == 0, k # ensure all outputs are zero (not nan, etc) |
0 commit comments