Skip to content

Commit 2902bae

Browse files
Minimal functionality for early feedback
1 parent ecd8256 commit 2902bae

File tree

2 files changed

+102
-0
lines changed

2 files changed

+102
-0
lines changed

pvlib/pvsystem.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@
77
import functools
88
import io
99
import itertools
10+
import numbers
1011
import os
1112
import inspect
1213
from urllib.request import urlopen
1314
import numpy as np
1415
from scipy import constants
16+
import scipy.optimize
1517
import pandas as pd
1618
from dataclasses import dataclass
1719
from abc import ABC, abstractmethod
@@ -3022,3 +3024,58 @@ def combine_loss_factors(index, *losses, fill_method='ffill'):
30223024
combined_factor *= (1 - loss)
30233025

30243026
return 1 - combined_factor
3027+
3028+
3029+
def _negative_total_power(current, *args):
3030+
"""
3031+
Compute negative of total power generated by devices in series at specified current.
3032+
"""
3033+
return -np.sum(current * v_from_i(current, *args))
3034+
3035+
3036+
def max_power_point_mismatched(
3037+
photocurrent, saturation_current, resistance_series, resistance_shunt, nNsVth,
3038+
):
3039+
"""Compute maximum power info for (possibly) mismatched set of devices in series."""
3040+
if all([isinstance(input, numbers.Number) for input in (
3041+
photocurrent, saturation_current, resistance_series, resistance_shunt, nNsVth
3042+
)]):
3043+
# There cannot be mismatch, so fall back to non-mismatch function.
3044+
return {
3045+
**max_power_point(
3046+
photocurrent,
3047+
saturation_current,
3048+
resistance_series,
3049+
resistance_shunt,
3050+
nNsVth
3051+
)
3052+
}
3053+
3054+
i_mp_0 = max_power_point(
3055+
np.mean(photocurrent),
3056+
np.mean(saturation_current),
3057+
np.mean(resistance_series),
3058+
np.mean(resistance_shunt),
3059+
np.mean(nNsVth),
3060+
)["i_mp"]
3061+
args = photocurrent, saturation_current, resistance_series, resistance_shunt, nNsVth
3062+
sol = scipy.optimize.minimize(_negative_total_power, i_mp_0, args)
3063+
3064+
if sol.success:
3065+
i_mp = sol.x[0]
3066+
v_mp = v_from_i(
3067+
i_mp,
3068+
photocurrent,
3069+
saturation_current,
3070+
resistance_series,
3071+
resistance_shunt,
3072+
nNsVth,
3073+
)
3074+
3075+
return {
3076+
"i_mp": i_mp,
3077+
"v_mp": v_mp,
3078+
"p_mp": i_mp * v_mp,
3079+
}
3080+
3081+
raise RuntimeError(f"unsuccessful solution: {sol}")

pvlib/tests/test_pvsystem.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import numpy as np
55
from numpy import nan, array
66
import pandas as pd
7+
import scipy.constants
78

89
import pytest
910
from .conftest import (
@@ -2549,3 +2550,47 @@ def test_Array_temperature_missing_parameters(model, keys):
25492550
array.temperature_model_parameters = params
25502551
with pytest.raises(KeyError, match=match):
25512552
array.get_cell_temperature(irrads, temps, winds, model)
2553+
2554+
2555+
@pytest.mark.parametrize(
2556+
'inputs',
2557+
[
2558+
{
2559+
"photocurrent": 6.2,
2560+
"saturation_current": 1.0e-8,
2561+
"n": 1.1,
2562+
"resistance_series": 0.0001,
2563+
"resistance_shunt": 5000.0,
2564+
"Ns": 60,
2565+
"T": 25.0,
2566+
},
2567+
{
2568+
"photocurrent": np.array([5.8, 6.2]),
2569+
"saturation_current": 1.0e-8,
2570+
"n": 1.1,
2571+
"resistance_series": 0.0001,
2572+
"resistance_shunt": 5000.0,
2573+
"Ns": 60,
2574+
"T": 25.0,
2575+
}
2576+
]
2577+
)
2578+
def test_max_power_point_mismatched(inputs):
2579+
"""Test max power point computaiton for mismatched devices in series."""
2580+
2581+
photocurrent = inputs["photocurrent"]
2582+
saturation_current = inputs["saturation_current"]
2583+
resistance_series = inputs["resistance_series"]
2584+
resistance_shunt = inputs["resistance_shunt"]
2585+
q_C = scipy.constants.value("elementary charge")
2586+
k_B_J_per_K = scipy.constants.value("Boltzmann constant")
2587+
T_K = scipy.constants.convert_temperature(inputs["T"], "Celsius", "Kelvin")
2588+
nNsVth = inputs["n"] * inputs["Ns"] * k_B_J_per_K * T_K / q_C
2589+
2590+
pvsystem.max_power_point_mismatched(
2591+
photocurrent,
2592+
saturation_current,
2593+
resistance_series,
2594+
resistance_shunt,
2595+
nNsVth,
2596+
)

0 commit comments

Comments
 (0)