Skip to content

Commit

Permalink
Add F and T_degC computation demo from MET station
Browse files Browse the repository at this point in the history
  • Loading branch information
markcampanelli committed Feb 12, 2024
1 parent 0af4dec commit aa8492c
Show file tree
Hide file tree
Showing 7 changed files with 471 additions and 6 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ jobs:
build:
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
os: [ubuntu-latest]
# Something causes ivcurves tests to take forever on macos and windows.
# os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ["3.10", "3.11", "3.12"]

runs-on: ${{ matrix.os }}
Expand Down
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,10 @@ NOTES:
[`numpy`](https://www.numpy.org/) and [`scipy`](https://www.scipy.org/) (e.g., using
[conda](https://docs.conda.io/en/latest/)), otherwise this setup will grab the default
versions from [PyPI](https://pypi.org/).
- The `demo` option adds the [matplotlib](https://matplotlib.org/) package in order to
run all the provided demonstrations in the `demos` directories.
- The `demo` option adds the [matplotlib](https://matplotlib.org/),
[pandas](https://pandas.pydata.org/), and
[pvlib-python](https://pvlib-python.readthedocs.io/) packages in order to run all the
provided demonstrations in the `demos` directories.

Verify your installation—
```terminal
Expand Down
26 changes: 25 additions & 1 deletion pvfit/modeling/dc/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"""

from enum import Enum
from typing import TypedDict
from typing import Protocol, TypedDict

import numpy
import scipy.constants
Expand Down Expand Up @@ -106,3 +106,27 @@ def get_scaled_thermal_voltage(
/ q_C
)
)


class IamFunction(Protocol):
"""Type definition for incident-angle modifier functions."""

def __call__(self, *, angle_deg: FloatArray) -> FloatArray:
...


def iam_factory(*, iam_angle_deg: FloatArray, iam_frac: FloatArray) -> IamFunction:
"""Generate interpolating function for incident-angle modifier (IAM)."""

def iam(*, angle_deg: FloatArray) -> FloatArray:
if numpy.any(numpy.logical_or(angle_deg < 0, angle_deg > 180)):
raise ValueError("angle_deg not between 0 and 180, inclusive")

iam_ = scipy.interpolate.PchipInterpolator(
iam_angle_deg, iam_frac, extrapolate=False
)(angle_deg)
iam_[90 < angle_deg] = 0.0

return iam_

return iam
36 changes: 34 additions & 2 deletions pvfit/modeling/dc/single_diode/equation/simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -349,13 +349,44 @@ def d2I_sum_diode_anode_dV2_at_V(V_V: FloatArray) -> FloatArray:
if V_V_ic.shape:
# Non-scalar case.
V_V = newton_result[0]
# Second return value is convergence array.
converged = newton_result[1]
not_converged = numpy.logical_not(converged)

if numpy.any(not_converged):
# Fall back to Newton's method for indices without convergence.
newton_result = newton(
I_sum_diode_anode_at_V,
V_V_ic[not_converged],
fprime=dI_sum_diode_anode_dV_at_V,
full_output=True,
**newton_options,
)
V_V[not_converged] = newton_result[0]

if numpy.array(newton_result[0]).shape:
# Non-scalar case. Second return value is convergence array.
converged[not_converged] = newton_result[1]
else:
# Scalar case. Second return value is RootResults object.
converged[not_converged] = newton_result[1].converged
else:
# Scalar case.
V_V = numpy.array(newton_result[1].root)
# Second return value is RootResults object with scalar converged attribute.
if not newton_result[1].converged:
# Fall back to Newton's method (which can only be scalar case).
newton_result = newton(
I_sum_diode_anode_at_V,
V_V_ic,
fprime=dI_sum_diode_anode_dV_at_V,
full_output=True,
**newton_options,
)

V_V = numpy.array(newton_result[0])
converged = numpy.array(newton_result[1].converged)

# Verify convergence, because newton() documentation says this should be checked.
# Verify overall convergence, which newton() documentation says should be checked.
numpy.testing.assert_equal(converged, True)

return V_V
Expand Down Expand Up @@ -511,6 +542,7 @@ def d2P_dV2(V_V):
model_parameters=model_parameters,
newton_options=newton_options,
)

V_mp_V_ic = numpy.array(3 / 4 * V_oc_V)

# Solve for V_mp_V using Newton's method.
Expand Down
15 changes: 15 additions & 0 deletions pvfit/modeling/dc/single_diode/model/demos/getting_started.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import pvfit.modeling.dc.single_diode.equation.simulation as sde_sim
import pvfit.modeling.dc.single_diode.model.demos.data as data
import pvfit.modeling.dc.single_diode.model.simple.auxiliary_equations as ae
import pvfit.modeling.dc.single_diode.model.simple.goodness_of_fit as goodness_of_fit
import pvfit.modeling.dc.single_diode.model.simple.inference_matrix as sdm_simple_inf_matrix
import pvfit.modeling.dc.single_diode.model.simple.inference_spec_sheet as sdm_simple_inf_spec_sheet

Expand Down Expand Up @@ -51,8 +52,15 @@
)
print("Fitting model parameters to performance matrix...done")

mape_mbpe_matrix, _ = goodness_of_fit.compute_matrix_mape_mbpe(
iv_performance_matrix=iv_performance_matrix,
model_parameters=model_parameters_matrix,
)

print("\nModel parameters from fit to performance matrix:")
pprint(model_parameters_matrix)
print("\nGoodness of fit:")
pprint(mape_mbpe_matrix)

# Compute parameters for I-V curve at STC using auxiliary equations to compute the
# model parameters passed to the single-diode equation (SDE).
Expand Down Expand Up @@ -171,8 +179,15 @@
)
print("Fitting model parameters to specification datasheet...done")

mape_mbpe_spec_sheet, _ = goodness_of_fit.compute_matrix_mape_mbpe(
iv_performance_matrix=iv_performance_matrix,
model_parameters=model_parameters_spec_sheet,
)

print("\nModel parameters from fit to specification datasheet:")
pprint(model_parameters_spec_sheet)
print("\nGoodness of fit:")
pprint(mape_mbpe_spec_sheet)

print("\nI-V curve parameters at STC using specification-datasheet fit:")
pprint(
Expand Down
Loading

0 comments on commit aa8492c

Please sign in to comment.