Repository navigation
Villalva Algorithm Pull Request #2878
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
Open
JFrederico2022
wants to merge
42
commits into
pvlib:main
Choose a base branch
from
JFrederico2022:main
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+979
−0
Open
Changes from all commits
Commits
Show all changes
42 commits
Select commit
Hold shift + click to select a range
8698c7a
Add files via upload
JFrederico2022 f468215
Merge branch 'pvlib:main' into main
JFrederico2022 16beb52
Delete pvlib/ivtools/sdm/Villalva.ipynb
JFrederico2022 07654d1
Add files via upload
JFrederico2022 547f679
Update __init__.py
JFrederico2022 5f29b13
Update pvsystem.py
JFrederico2022 51fdd23
Add files via upload
JFrederico2022 eb878f6
Update pvlib/ivtools/sdm/villalva.py
JFrederico2022 386c004
Update pvlib/ivtools/sdm/villalva.py
JFrederico2022 308fe5f
Update villalva.py
JFrederico2022 e8b541e
Update pvlib/ivtools/sdm/villalva.py
JFrederico2022 994732b
Update pvlib/ivtools/sdm/villalva.py
JFrederico2022 1b6898d
Update pvlib/ivtools/sdm/villalva.py
JFrederico2022 1b638ac
Update pvlib/ivtools/sdm/villalva.py
JFrederico2022 0ed22d0
Update pvlib/ivtools/sdm/villalva.py
JFrederico2022 eb33c3e
Update pvlib/ivtools/sdm/villalva.py
JFrederico2022 c37846c
Update pvlib/ivtools/sdm/villalva.py
JFrederico2022 6ffbb12
Update pvlib/pvsystem.py
JFrederico2022 e3f6400
Update pvlib/ivtools/sdm/__init__.py
JFrederico2022 2ebcb2d
Update pvlib/pvsystem.py
JFrederico2022 9ea7601
Update villalva.py
JFrederico2022 5a7ea02
Add Villalva parameters to PV modeling documentation
JFrederico2022 d18881d
Revise references in pvsystem.py documentation
JFrederico2022 01f0585
Suppress E231 warnings in plot_villalva.py
JFrederico2022 09b970e
Add fit_villalva function to parameters documentation
JFrederico2022 6b62931
Fix return statement indentation in pvsystem.py
JFrederico2022 7307b50
Import fit_villalva function in __init__.py
JFrederico2022 af96cee
Update pvlib/ivtools/sdm/villalva.py
JFrederico2022 534df7c
Update pvlib/ivtools/sdm/villalva.py
JFrederico2022 a3f1f99
Update pvlib/pvsystem.py
JFrederico2022 07359d8
Update pvlib/pvsystem.py
JFrederico2022 05aa194
Update pvlib/pvsystem.py
JFrederico2022 6386ac6
Update pvlib/pvsystem.py
JFrederico2022 c0de33a
Update pvlib/ivtools/sdm/villalva.py
JFrederico2022 d397546
Update pvlib/ivtools/sdm/villalva.py
JFrederico2022 23514ad
Update pvlib/ivtools/sdm/villalva.py
JFrederico2022 7832f4f
Update pvlib/ivtools/sdm/villalva.py
JFrederico2022 d997727
Update pvlib/pvsystem.py
JFrederico2022 a2ea5f4
Add files via upload
JFrederico2022 7bd8710
Refine documentation for Villalva SDM parameters
JFrederico2022 f63ba4a
Implement test for calcparams_villalva function
JFrederico2022 bc3194c
Update title for Villalva model example
JFrederico2022 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,273 @@ | ||
| """Functions for fitting the Villalva single-diode model.""" | ||
|
|
||
| import numpy as np | ||
| import pandas as pd | ||
|
|
||
| from scipy import constants | ||
|
|
||
| from pvlib import pvsystem | ||
|
|
||
|
|
||
| def _villalva_params_at_rs( | ||
| resistance_series, | ||
| v_mp, | ||
| i_mp, | ||
| v_oc, | ||
| i_sc, | ||
| a_ref, | ||
| ): | ||
| """Calculate ``I_L``, ``I_o`` and ``R_sh`` for one candidate ``R_s``.""" | ||
| exp_voc = np.expm1(v_oc / a_ref) | ||
| exp_vmp = np.expm1((v_mp + i_mp * resistance_series) / a_ref) | ||
|
|
||
| p_mp = v_mp * i_mp | ||
|
|
||
| # Algebraic combination of Villalva's equations: | ||
| # | ||
| # I_L = (R_sh + R_s) / R_sh * I_sc | ||
| # | ||
| # I_o = (I_L - V_oc / R_sh) / (exp(V_oc / a_ref) - 1) | ||
| # | ||
| # and the R_sh(R_s) relation obtained at the MPP. | ||
| a_term = ( | ||
| v_mp * i_sc | ||
| - v_mp * i_sc * exp_vmp / exp_voc | ||
| - p_mp | ||
| ) | ||
|
|
||
| b_term = ( | ||
| v_mp * i_sc * resistance_series | ||
| - v_mp | ||
| * (i_sc * resistance_series - v_oc) | ||
| * exp_vmp | ||
| / exp_voc | ||
| ) | ||
|
|
||
| resistance_shunt = ( | ||
| v_mp * (v_mp + i_mp * resistance_series) - b_term | ||
| ) / a_term | ||
|
|
||
| photocurrent = ( | ||
| (resistance_shunt + resistance_series) | ||
| / resistance_shunt | ||
| * i_sc | ||
| ) | ||
|
|
||
| saturation_current = ( | ||
| photocurrent - v_oc / resistance_shunt | ||
| ) / exp_voc | ||
|
|
||
| return photocurrent, saturation_current, resistance_shunt | ||
|
|
||
|
|
||
| def fit_villalva( | ||
| v_mp, | ||
| i_mp, | ||
| v_oc, | ||
| i_sc, | ||
| alpha_sc, | ||
| beta_voc, | ||
| cells_in_series, | ||
| diode_factor, | ||
| temp_ref=25.0, | ||
| irrad_ref=1000.0, | ||
| rs_step=1e-4, | ||
| rs_max=None, | ||
| ): | ||
| r"""Fit Villalva single-diode model to datasheet values. | ||
|
|
||
| Parameter extraction for Villalva's single-diode model [1]_ is described in [2]_. | ||
| Parameter estimation increments the series resistance from zero. For each | ||
| candidate :math:`R_s`, the corresponding :math:`R_{sh}`, :math:`I_L`, and | ||
| :math:`I_0` are calculated and the maximum power of the resulting single-diode | ||
| equation is evaluated. The returned parameters solution minimizes the absolute | ||
| difference between the modeled maximum power and the datasheet maximum | ||
| power at reference conditions. | ||
|
|
||
| The dimensionless diode ideality factor :math:`n` is supplied by the user. | ||
| The modified ideality factor at reference conditions is calculated as | ||
|
|
||
| .. math:: | ||
|
|
||
| a_{ref} = n N_s k T_{ref} / q. | ||
|
|
||
| Parameters | ||
| ---------- | ||
| v_mp : float | ||
| Maximum-power voltage at reference conditions. [V] | ||
| i_mp : float | ||
| Maximum-power current at reference conditions. [A] | ||
| v_oc : float | ||
| Open-circuit voltage at reference conditions. [V] | ||
| i_sc : float | ||
| Short-circuit current at reference conditions. [A] | ||
| alpha_sc : float | ||
| Short-circuit current temperature coefficient. [A/K] | ||
| beta_voc : float | ||
| Open-circuit voltage temperature coefficient. [V/K] | ||
| cells_in_series : int | ||
| Effective number of cells or junctions connected in series. | ||
| diode_factor : float | ||
| Dimensionless diode ideality factor. [unitless] | ||
| temp_ref : float, default 25 | ||
| Reference cell temperature. [°C] | ||
| irrad_ref : float, default 1000 | ||
| Reference irradiance. [Wm⁻²] | ||
| rs_step : float, default 1e-4 | ||
| Increment used for the series-resistance sweep. [ohm] | ||
| rs_max : float, optional | ||
| Maximum series resistance considered. If ``None``, ``v_oc / i_sc`` | ||
| is used. [ohm] | ||
|
|
||
| Returns | ||
| ------- | ||
| params : dict | ||
| Fitted reference-condition Villalva parameters. The dictionary | ||
| contains ``I_L_ref``, ``I_o_ref``, ``R_s``, ``R_sh_ref``, ``a_ref``, | ||
| ``alpha_sc``, ``beta_voc``, ``i_sc_ref``, ``v_oc_ref``, | ||
| ``irrad_ref``, and ``temp_ref``. | ||
| history : pandas.DataFrame | ||
| Full fitting history for all valid values of ``R_s`` evaluated by the | ||
| algorithm. | ||
|
|
||
| Raises | ||
| ------ | ||
| ValueError | ||
| If the minimum shunt resistance is not positive. | ||
| RuntimeError | ||
| If no valid solution is found. | ||
|
|
||
| Notes | ||
| ----- | ||
| The returned reference parameters are intended for use with | ||
| :py:func:`pvlib.pvsystem.calcparams_villalva`. I-V curve points can then | ||
| be calculated with :py:func:`pvlib.pvsystem.singlediode` or | ||
| :py:func:`pvlib.pvsystem.i_from_v`. | ||
|
|
||
| References | ||
| ---------- | ||
| .. [1] M. G. Villalva, J. R. Gazoli, and E. Ruppert Filho, "Comprehensive | ||
| approach to modeling and simulation of photovoltaic arrays," IEEE Trans. | ||
| Power Electron., vol. 24, no. 5, pp. 1198-1208, May 2009. | ||
| :doi:`10.1109/TPEL.2009.2013862` | ||
| .. [2] M. G. Villalva, "Conversor eletrônico de potência trifásico para | ||
| sistema fotovoltaico conectado à rede elétrica," Ph.D. dissertation, | ||
| Faculdade de Engenharia Elétrica e de Computação, Universidade Estadual | ||
| de Campinas (UNICAMP), Campinas, Brazil, 2010. | ||
| :doi:`10.47749/T/UNICAMP.2010.781324` | ||
| """ | ||
|
JFrederico2022 marked this conversation as resolved.
|
||
| temp_ref_k = temp_ref + 273.15 | ||
|
|
||
| # a_ref = a * Ns * kT/q | ||
| a_ref = ( | ||
| diode_factor | ||
| * cells_in_series | ||
| * constants.k | ||
| * temp_ref_k | ||
| / constants.e | ||
| ) | ||
|
|
||
| p_mp_ref = v_mp * i_mp | ||
|
|
||
| # Villalva minimum shunt resistance. | ||
| r_sh_min = v_mp / (i_sc - i_mp) - (v_oc - v_mp) / i_mp | ||
|
|
||
| if r_sh_min <= 0: | ||
| raise ValueError("Villalva R_sh_min must be positive.") | ||
|
|
||
| if rs_max is None: | ||
| rs_max = v_oc / i_sc | ||
|
|
||
| rs_values = np.arange(0.0, rs_max + 0.5 * rs_step, rs_step) | ||
|
|
||
| # Calculate parameters for all candidate series resistances. | ||
| with np.errstate(divide="ignore", invalid="ignore", over="ignore"): | ||
| photocurrent, saturation_current, resistance_shunt = ( | ||
| _villalva_params_at_rs( | ||
| rs_values, | ||
| v_mp, | ||
| i_mp, | ||
| v_oc, | ||
| i_sc, | ||
| a_ref, | ||
| ) | ||
| ) | ||
|
|
||
| # Exclude non-finite and physically invalid parameters. | ||
| valid = ( | ||
| np.isfinite(photocurrent) | ||
| & np.isfinite(saturation_current) | ||
| & np.isfinite(resistance_shunt) | ||
| & (resistance_shunt >= r_sh_min) | ||
| & (photocurrent > 0) | ||
| & (saturation_current > 0) | ||
| ) | ||
|
|
||
| if not np.any(valid): | ||
| raise RuntimeError("No valid Villalva solution was found.") | ||
|
|
||
| rs_values = rs_values[valid] | ||
| photocurrent = photocurrent[valid] | ||
| saturation_current = saturation_current[valid] | ||
| resistance_shunt = resistance_shunt[valid] | ||
|
|
||
| # Calculate the maximum power point for all valid candidates. | ||
| with np.errstate(divide="ignore", invalid="ignore", over="ignore"): | ||
| mpp = pvsystem.max_power_point( | ||
| photocurrent=photocurrent, | ||
| saturation_current=saturation_current, | ||
| resistance_series=rs_values, | ||
| resistance_shunt=resistance_shunt, | ||
| nNsVth=a_ref, | ||
| method="brentq", | ||
| ) | ||
|
|
||
| v_mp_model = np.asarray(mpp["v_mp"]) | ||
| i_mp_model = np.asarray(mpp["i_mp"]) | ||
| p_mp_model = np.asarray(mpp["p_mp"]) | ||
|
|
||
| power_error = p_mp_model - p_mp_ref | ||
|
|
||
| # Exclude non-finite maximum power point results. | ||
| valid_mpp = ( | ||
| np.isfinite(v_mp_model) | ||
| & np.isfinite(i_mp_model) | ||
| & np.isfinite(p_mp_model) | ||
| & np.isfinite(power_error) | ||
| ) | ||
|
|
||
| if not np.any(valid_mpp): | ||
| raise RuntimeError("No valid Villalva solution was found.") | ||
|
|
||
| history = pd.DataFrame( | ||
| { | ||
| "R_s": rs_values[valid_mpp], | ||
| "R_sh_ref": resistance_shunt[valid_mpp], | ||
| "I_L_ref": photocurrent[valid_mpp], | ||
| "I_o_ref": saturation_current[valid_mpp], | ||
| "v_mp_model": v_mp_model[valid_mpp], | ||
| "i_mp_model": i_mp_model[valid_mpp], | ||
| "p_mp_model": p_mp_model[valid_mpp], | ||
| "p_mp_ref": p_mp_ref, | ||
| "power_error": power_error[valid_mpp], | ||
| "abs_power_error": np.abs(power_error[valid_mpp]), | ||
| } | ||
| ) | ||
|
|
||
| best = history.loc[history["abs_power_error"].idxmin()] | ||
|
|
||
| params = { | ||
| "I_L_ref": float(best["I_L_ref"]), | ||
| "I_o_ref": float(best["I_o_ref"]), | ||
| "R_s": float(best["R_s"]), | ||
| "R_sh_ref": float(best["R_sh_ref"]), | ||
| "a_ref": float(a_ref), | ||
| "alpha_sc": alpha_sc, | ||
| "beta_voc": beta_voc, | ||
| "i_sc_ref": i_sc, | ||
| "v_oc_ref": v_oc, | ||
| "irrad_ref": irrad_ref, | ||
| "temp_ref": temp_ref, | ||
| } | ||
|
|
||
| return params, history | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.