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
|
@@ -0,0 +1,630 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from scipy import constants
|
|
4
|
+
|
|
5
|
+
from pvlib.pvsystem import calcparams_pvsyst
|
|
6
|
+
from pvlib.singlediode import bishop88_mpp
|
|
7
|
+
|
|
8
|
+
from pvlib.ivtools.utils import rectify_iv_curve
|
|
9
|
+
from pvlib.ivtools.sde import _fit_sandia_cocontent
|
|
10
|
+
|
|
11
|
+
from pvlib.tools import _first_order_centered_difference
|
|
12
|
+
|
|
13
|
+
from pvlib.ivtools.sdm._fit_desoto_pvsyst_sandia import (
|
|
14
|
+
_extract_sdm_params, _initial_iv_params, _update_iv_params
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
from pvlib.pvsystem import (
|
|
18
|
+
_pvsyst_Rsh, _pvsyst_IL, _pvsyst_Io, _pvsyst_nNsVth, _pvsyst_gamma
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
CONSTANTS = {'E0': 1000.0, 'T0': 25.0, 'k': constants.k, 'q': constants.e}
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def fit_pvsyst_sandia(ivcurves, specs, const=None, maxiter=5, eps1=1.e-3):
|
|
25
|
+
"""
|
|
26
|
+
Estimate parameters for the PVsyst module performance model.
|
|
27
|
+
|
|
28
|
+
Parameters
|
|
29
|
+
----------
|
|
30
|
+
ivcurves : dict
|
|
31
|
+
i : array
|
|
32
|
+
One array element for each IV curve. The jth element is itself an
|
|
33
|
+
array of current for jth IV curve (same length as v[j]) [A]
|
|
34
|
+
v : array
|
|
35
|
+
One array element for each IV curve. The jth element is itself an
|
|
36
|
+
array of voltage for jth IV curve (same length as i[j]) [V]
|
|
37
|
+
ee : array
|
|
38
|
+
effective irradiance for each IV curve, i.e., POA broadband
|
|
39
|
+
irradiance adjusted by solar spectrum modifier [W / m^2]
|
|
40
|
+
tc : array
|
|
41
|
+
cell temperature for each IV curve [C]
|
|
42
|
+
i_sc : array
|
|
43
|
+
short circuit current for each IV curve [A]
|
|
44
|
+
v_oc : array
|
|
45
|
+
open circuit voltage for each IV curve [V]
|
|
46
|
+
i_mp : array
|
|
47
|
+
current at max power point for each IV curve [A]
|
|
48
|
+
v_mp : array
|
|
49
|
+
voltage at max power point for each IV curve [V]
|
|
50
|
+
|
|
51
|
+
specs : dict
|
|
52
|
+
cells_in_series : int
|
|
53
|
+
number of cells in series
|
|
54
|
+
alpha_sc : float
|
|
55
|
+
temperature coefficient of isc [A/C]
|
|
56
|
+
|
|
57
|
+
const : dict
|
|
58
|
+
E0 : float
|
|
59
|
+
effective irradiance at STC, default 1000 [W/m^2]
|
|
60
|
+
T0 : float
|
|
61
|
+
cell temperature at STC, default 25 [C]
|
|
62
|
+
k : float
|
|
63
|
+
Boltzmann's constant [J/K]
|
|
64
|
+
q : float
|
|
65
|
+
elementary charge [Coulomb]
|
|
66
|
+
|
|
67
|
+
maxiter : int, default 5
|
|
68
|
+
input that sets the maximum number of iterations for the parameter
|
|
69
|
+
updating part of the algorithm.
|
|
70
|
+
|
|
71
|
+
eps1: float, default 1e-3
|
|
72
|
+
Tolerance for the IV curve fitting. The parameter updating stops when
|
|
73
|
+
absolute values of the percent change in mean, max and standard
|
|
74
|
+
deviation of Imp, Vmp and Pmp between iterations are all less than
|
|
75
|
+
eps1, or when the number of iterations exceeds maxiter.
|
|
76
|
+
|
|
77
|
+
Returns
|
|
78
|
+
-------
|
|
79
|
+
dict
|
|
80
|
+
I_L_ref : float
|
|
81
|
+
light current at STC [A]
|
|
82
|
+
I_o_ref : float
|
|
83
|
+
dark current at STC [A]
|
|
84
|
+
EgRef : float
|
|
85
|
+
effective band gap at STC [eV]
|
|
86
|
+
R_s : float
|
|
87
|
+
series resistance at STC [ohm]
|
|
88
|
+
R_sh_ref : float
|
|
89
|
+
shunt resistance at STC [ohm]
|
|
90
|
+
R_sh_0 : float
|
|
91
|
+
shunt resistance at zero irradiance [ohm]
|
|
92
|
+
R_sh_exp : float
|
|
93
|
+
exponential factor defining decrease in shunt resistance with
|
|
94
|
+
increasing effective irradiance
|
|
95
|
+
gamma_ref : float
|
|
96
|
+
diode (ideality) factor at STC [unitless]
|
|
97
|
+
mu_gamma : float
|
|
98
|
+
temperature coefficient for diode (ideality) factor [1/K]
|
|
99
|
+
cells_in_series : int
|
|
100
|
+
number of cells in series
|
|
101
|
+
iph : array
|
|
102
|
+
light current for each IV curve [A]
|
|
103
|
+
io : array
|
|
104
|
+
dark current for each IV curve [A]
|
|
105
|
+
rs : array
|
|
106
|
+
series resistance for each IV curve [ohm]
|
|
107
|
+
rsh : array
|
|
108
|
+
shunt resistance for each IV curve [ohm]
|
|
109
|
+
u : array
|
|
110
|
+
boolean for each IV curve indicating that the parameter values
|
|
111
|
+
are deemed reasonable by the private function ``_filter_params``
|
|
112
|
+
|
|
113
|
+
Notes
|
|
114
|
+
-----
|
|
115
|
+
The PVsyst module performance model is described in [1]_, [2]_, and [3]_.
|
|
116
|
+
The fitting method is documented in [4]_, [5]_, and [6]_.
|
|
117
|
+
Ported from PVLib Matlab [7]_.
|
|
118
|
+
|
|
119
|
+
References
|
|
120
|
+
----------
|
|
121
|
+
.. [1] K. Sauer, T. Roessler, C. W. Hansen, Modeling the Irradiance and
|
|
122
|
+
Temperature Dependence of Photovoltaic Modules in PVsyst, IEEE Journal
|
|
123
|
+
of Photovoltaics v5(1), January 2015.
|
|
124
|
+
:doi:`10.1109/JPHOTOV.2014.2364133`
|
|
125
|
+
.. [2] A. Mermoud, PV Modules modeling, Presentation at the 2nd PV
|
|
126
|
+
Performance Modeling Workshop, Santa Clara, CA, May 2013
|
|
127
|
+
.. [3] A. Mermoud, T. Lejeuene, Performance Assessment of a Simulation
|
|
128
|
+
Model for PV modules of any available technology, 25th European
|
|
129
|
+
Photovoltaic Solar Energy Conference, Valencia, Spain, Sept. 2010
|
|
130
|
+
.. [4] C. Hansen, Estimating Parameters for the PVsyst Version 6
|
|
131
|
+
Photovoltaic Module Performance Model, Sandia National Laboratories
|
|
132
|
+
Report SAND2015-8598. :doi:`10.2172/1223058`
|
|
133
|
+
.. [5] C. Hansen, Parameter Estimation for Single Diode Models of
|
|
134
|
+
Photovoltaic Modules, Sandia National Laboratories Report SAND2015-2065.
|
|
135
|
+
:doi:`10.2172/1177157`
|
|
136
|
+
.. [6] C. Hansen, Estimation of Parameters for Single Diode Models using
|
|
137
|
+
Measured IV Curves, Proc. of the 39th IEEE PVSC, June 2013.
|
|
138
|
+
:doi:`10.1109/PVSC.2013.6744135`
|
|
139
|
+
.. [7] PVLib MATLAB https://github.com/sandialabs/MATLAB_PV_LIB
|
|
140
|
+
"""
|
|
141
|
+
|
|
142
|
+
if const is None:
|
|
143
|
+
const = CONSTANTS
|
|
144
|
+
|
|
145
|
+
ee = ivcurves['ee']
|
|
146
|
+
tc = ivcurves['tc']
|
|
147
|
+
tck = tc + 273.15
|
|
148
|
+
isc = ivcurves['i_sc']
|
|
149
|
+
voc = ivcurves['v_oc']
|
|
150
|
+
imp = ivcurves['i_mp']
|
|
151
|
+
vmp = ivcurves['v_mp']
|
|
152
|
+
|
|
153
|
+
# Cell Thermal Voltage
|
|
154
|
+
vth = const['k'] / const['q'] * tck
|
|
155
|
+
|
|
156
|
+
n = len(ivcurves['v_oc'])
|
|
157
|
+
|
|
158
|
+
# Initial estimate of Rsh used to obtain the diode factor gamma0 and diode
|
|
159
|
+
# temperature coefficient mu_gamma. Rsh is estimated using the co-content
|
|
160
|
+
# integral method.
|
|
161
|
+
|
|
162
|
+
rsh = np.ones(n)
|
|
163
|
+
for j in range(n):
|
|
164
|
+
voltage, current = rectify_iv_curve(ivcurves['v'][j], ivcurves['i'][j])
|
|
165
|
+
# initial estimate of Rsh, from integral over voltage regression
|
|
166
|
+
# [5] Step 3a; [6] Step 3a
|
|
167
|
+
_, _, _, rsh[j], _ = _fit_sandia_cocontent(
|
|
168
|
+
voltage, current, vth[j] * specs['cells_in_series'])
|
|
169
|
+
|
|
170
|
+
gamma_ref, mu_gamma = _fit_pvsyst_sandia_gamma(voc, isc, rsh, vth, tck,
|
|
171
|
+
specs, const)
|
|
172
|
+
|
|
173
|
+
badgamma = np.isnan(gamma_ref) or np.isnan(mu_gamma) \
|
|
174
|
+
or not np.isreal(gamma_ref) or not np.isreal(mu_gamma)
|
|
175
|
+
|
|
176
|
+
if badgamma:
|
|
177
|
+
raise RuntimeError(
|
|
178
|
+
"Failed to estimate the diode (ideality) factor parameter;"
|
|
179
|
+
" aborting parameter estimation.")
|
|
180
|
+
|
|
181
|
+
gamma = gamma_ref + mu_gamma * (tc - const['T0'])
|
|
182
|
+
nnsvth = gamma * (vth * specs['cells_in_series'])
|
|
183
|
+
|
|
184
|
+
# For each IV curve, sequentially determine initial values for Io, Rs,
|
|
185
|
+
# and Iph [5] Step 3a; [6] Step 3
|
|
186
|
+
iph, io, rs, u = _initial_iv_params(ivcurves, ee, voc, isc, rsh,
|
|
187
|
+
nnsvth)
|
|
188
|
+
|
|
189
|
+
# Update values for each IV curve to converge at vmp, imp, voc and isc
|
|
190
|
+
iph, io, rs, rsh, u = _update_iv_params(voc, isc, vmp, imp, ee,
|
|
191
|
+
iph, io, rs, rsh, nnsvth, u,
|
|
192
|
+
maxiter, eps1)
|
|
193
|
+
|
|
194
|
+
# get single diode models from converged values for each IV curve
|
|
195
|
+
pvsyst = _extract_sdm_params(ee, tc, iph, io, rs, rsh, gamma, u,
|
|
196
|
+
specs, const, model='pvsyst')
|
|
197
|
+
# Add parameters estimated in this function
|
|
198
|
+
pvsyst['gamma_ref'] = gamma_ref
|
|
199
|
+
pvsyst['mu_gamma'] = mu_gamma
|
|
200
|
+
pvsyst['cells_in_series'] = specs['cells_in_series']
|
|
201
|
+
|
|
202
|
+
return pvsyst
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
def _fit_pvsyst_sandia_gamma(voc, isc, rsh, vth, tck, specs, const):
|
|
206
|
+
# Estimate the diode factor gamma from Isc-Voc data. Method incorporates
|
|
207
|
+
# temperature dependence by means of the equation for Io
|
|
208
|
+
|
|
209
|
+
y = np.log(isc - voc / rsh) - 3. * np.log(tck / (const['T0'] + 273.15))
|
|
210
|
+
x1 = const['q'] / const['k'] * (1. / (const['T0'] + 273.15) - 1. / tck)
|
|
211
|
+
x2 = voc / (vth * specs['cells_in_series'])
|
|
212
|
+
uu = np.logical_or(np.isnan(y), np.isnan(x1), np.isnan(x2))
|
|
213
|
+
|
|
214
|
+
x = np.vstack((np.ones(len(x1[~uu])), x1[~uu], -x1[~uu] *
|
|
215
|
+
(tck[~uu] - (const['T0'] + 273.15)), x2[~uu],
|
|
216
|
+
-x2[~uu] * (tck[~uu] - (const['T0'] + 273.15)))).T
|
|
217
|
+
alpha = np.linalg.lstsq(x, y[~uu], rcond=None)[0]
|
|
218
|
+
|
|
219
|
+
gamma_ref = 1. / alpha[3]
|
|
220
|
+
mu_gamma = alpha[4] / alpha[3] ** 2
|
|
221
|
+
return gamma_ref, mu_gamma
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
def pvsyst_temperature_coeff(alpha_sc, gamma_ref, mu_gamma, I_L_ref, I_o_ref,
|
|
225
|
+
R_sh_ref, R_sh_0, R_s, cells_in_series,
|
|
226
|
+
R_sh_exp=5.5, EgRef=1.121, irrad_ref=1000,
|
|
227
|
+
temp_ref=25):
|
|
228
|
+
r"""
|
|
229
|
+
Calculates the temperature coefficient of power for a pvsyst single
|
|
230
|
+
diode model.
|
|
231
|
+
|
|
232
|
+
The temperature coefficient is determined as the numerical derivative
|
|
233
|
+
:math:`\frac{dP}{dT}` at the maximum power point at reference conditions
|
|
234
|
+
[1]_.
|
|
235
|
+
|
|
236
|
+
Parameters
|
|
237
|
+
----------
|
|
238
|
+
alpha_sc : float
|
|
239
|
+
The short-circuit current temperature coefficient of the module. [A/C]
|
|
240
|
+
|
|
241
|
+
gamma_ref : float
|
|
242
|
+
The diode ideality factor. [unitless]
|
|
243
|
+
|
|
244
|
+
mu_gamma : float
|
|
245
|
+
The temperature coefficient for the diode ideality factor. [1/K]
|
|
246
|
+
|
|
247
|
+
I_L_ref : float
|
|
248
|
+
The light-generated current (or photocurrent) at reference conditions.
|
|
249
|
+
[A]
|
|
250
|
+
|
|
251
|
+
I_o_ref : float
|
|
252
|
+
The dark or diode reverse saturation current at reference conditions.
|
|
253
|
+
[A]
|
|
254
|
+
|
|
255
|
+
R_sh_ref : float
|
|
256
|
+
The shunt resistance at reference conditions. [ohm]
|
|
257
|
+
|
|
258
|
+
R_sh_0 : float
|
|
259
|
+
The shunt resistance at zero irradiance conditions. [ohm]
|
|
260
|
+
|
|
261
|
+
R_s : float
|
|
262
|
+
The series resistance at reference conditions. [ohm]
|
|
263
|
+
|
|
264
|
+
cells_in_series : int
|
|
265
|
+
The number of cells connected in series.
|
|
266
|
+
|
|
267
|
+
R_sh_exp : float, default 5.5
|
|
268
|
+
The exponent in the equation for shunt resistance. [unitless]
|
|
269
|
+
|
|
270
|
+
EgRef : float, default 1.121
|
|
271
|
+
The energy bandgap of the module's cells at reference temperature.
|
|
272
|
+
Default of 1.121 eV is for crystalline silicon. Must be positive. [eV]
|
|
273
|
+
|
|
274
|
+
irrad_ref : float, default 1000
|
|
275
|
+
Reference irradiance. [W/m^2].
|
|
276
|
+
|
|
277
|
+
temp_ref : float, default 25
|
|
278
|
+
Reference cell temperature. [C]
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
Returns
|
|
282
|
+
-------
|
|
283
|
+
gamma_pdc : float
|
|
284
|
+
Temperature coefficient of power at maximum power point at reference
|
|
285
|
+
conditions. [1/C]
|
|
286
|
+
|
|
287
|
+
References
|
|
288
|
+
----------
|
|
289
|
+
.. [1] K. Sauer, T. Roessler, C. W. Hansen, Modeling the Irradiance and
|
|
290
|
+
Temperature Dependence of Photovoltaic Modules in PVsyst, IEEE Journal
|
|
291
|
+
of Photovoltaics v5(1), January 2015.
|
|
292
|
+
"""
|
|
293
|
+
|
|
294
|
+
def maxp(temp_cell, irrad_ref, alpha_sc, gamma_ref, mu_gamma, I_L_ref,
|
|
295
|
+
I_o_ref, R_sh_ref, R_sh_0, R_s, cells_in_series, R_sh_exp, EgRef,
|
|
296
|
+
temp_ref):
|
|
297
|
+
params = calcparams_pvsyst(
|
|
298
|
+
irrad_ref, temp_cell, alpha_sc, gamma_ref, mu_gamma, I_L_ref,
|
|
299
|
+
I_o_ref, R_sh_ref, R_sh_0, R_s, cells_in_series, R_sh_exp, EgRef,
|
|
300
|
+
irrad_ref, temp_ref)
|
|
301
|
+
res = bishop88_mpp(*params)
|
|
302
|
+
return res[2]
|
|
303
|
+
|
|
304
|
+
args = (irrad_ref, alpha_sc, gamma_ref, mu_gamma, I_L_ref,
|
|
305
|
+
I_o_ref, R_sh_ref, R_sh_0, R_s, cells_in_series, R_sh_exp, EgRef,
|
|
306
|
+
temp_ref)
|
|
307
|
+
pmp = maxp(temp_ref, *args)
|
|
308
|
+
gamma_pdc = _first_order_centered_difference(maxp, x0=temp_ref, args=args)
|
|
309
|
+
|
|
310
|
+
return gamma_pdc / pmp
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
def fit_pvsyst_iec61853_sandia_2025(effective_irradiance, temp_cell,
|
|
314
|
+
i_sc, v_oc, i_mp, v_mp,
|
|
315
|
+
cells_in_series, EgRef=1.121,
|
|
316
|
+
alpha_sc=None, beta_mp=None,
|
|
317
|
+
R_s=None, r_sh_coeff=0.12,
|
|
318
|
+
min_Rsh_irradiance=None,
|
|
319
|
+
irradiance_tolerance=20,
|
|
320
|
+
temperature_tolerance=1):
|
|
321
|
+
"""
|
|
322
|
+
Estimate parameters for the PVsyst module performance model using
|
|
323
|
+
IEC 61853-1 matrix measurements.
|
|
324
|
+
|
|
325
|
+
Parameters
|
|
326
|
+
----------
|
|
327
|
+
effective_irradiance : array
|
|
328
|
+
Effective irradiance for each test condition [W/m²]
|
|
329
|
+
temp_cell : array
|
|
330
|
+
Cell temperature for each test condition [C]
|
|
331
|
+
i_sc : array
|
|
332
|
+
Short circuit current for each test condition [A]
|
|
333
|
+
v_oc : array
|
|
334
|
+
Open circuit voltage for each test condition [V]
|
|
335
|
+
i_mp : array
|
|
336
|
+
Current at maximum power point for each test condition [A]
|
|
337
|
+
v_mp : array
|
|
338
|
+
Voltage at maximum power point for each test condition [V]
|
|
339
|
+
cells_in_series : int
|
|
340
|
+
The number of cells connected in series.
|
|
341
|
+
EgRef : float, optional
|
|
342
|
+
The energy bandgap at reference temperature in units of eV.
|
|
343
|
+
1.121 eV for crystalline silicon. EgRef must be >0.
|
|
344
|
+
alpha_sc : float, optional
|
|
345
|
+
Temperature coefficient of short circuit current. If not specified,
|
|
346
|
+
it will be estimated using the ``i_sc`` values at irradiance of
|
|
347
|
+
1000 W/m2. [A/K]
|
|
348
|
+
beta_mp : float, optional
|
|
349
|
+
Temperature coefficient of maximum power voltage. If not specified,
|
|
350
|
+
it will be estimated using the ``v_mp`` values at irradiance of
|
|
351
|
+
1000 W/m2. [1/K]
|
|
352
|
+
R_s : float, optional
|
|
353
|
+
Series resistance value. If not provided, a value will be estimated
|
|
354
|
+
from the input measurements. [ohm]
|
|
355
|
+
r_sh_coeff : float, default 0.12
|
|
356
|
+
Shunt resistance fitting coefficient. The default value is taken
|
|
357
|
+
from [1]_.
|
|
358
|
+
min_Rsh_irradiance : float, optional
|
|
359
|
+
Irradiance threshold below which values are excluded when estimating
|
|
360
|
+
shunt resistance parameter values. May be useful for modules
|
|
361
|
+
with problematic low-light measurements. [W/m²]
|
|
362
|
+
irradiance_tolerance : float, default 20
|
|
363
|
+
Tolerance for irradiance variation around the STC value.
|
|
364
|
+
The default value corresponds to a +/- 2% interval around the STC
|
|
365
|
+
value of 1000 W/m². [W/m²]
|
|
366
|
+
temperature_tolerance : float, default 1
|
|
367
|
+
Tolerance for temperature variation around the STC value.
|
|
368
|
+
The default value corresponds to a +/- 1 degree interval around the STC
|
|
369
|
+
value of 25 degrees. [C]
|
|
370
|
+
|
|
371
|
+
Returns
|
|
372
|
+
-------
|
|
373
|
+
dict
|
|
374
|
+
alpha_sc : float
|
|
375
|
+
short circuit current temperature coefficient [A/K]
|
|
376
|
+
gamma_ref : float
|
|
377
|
+
diode (ideality) factor at STC [unitless]
|
|
378
|
+
mu_gamma : float
|
|
379
|
+
temperature coefficient for diode (ideality) factor [1/K]
|
|
380
|
+
I_L_ref : float
|
|
381
|
+
light current at STC [A]
|
|
382
|
+
I_o_ref : float
|
|
383
|
+
dark current at STC [A]
|
|
384
|
+
R_sh_ref : float
|
|
385
|
+
shunt resistance at STC [ohm]
|
|
386
|
+
R_sh_0 : float
|
|
387
|
+
shunt resistance at zero irradiance [ohm]
|
|
388
|
+
R_sh_exp : float
|
|
389
|
+
exponential factor defining decrease in shunt resistance with
|
|
390
|
+
increasing effective irradiance
|
|
391
|
+
R_s : float
|
|
392
|
+
series resistance at STC [ohm]
|
|
393
|
+
cells_in_series : int
|
|
394
|
+
number of cells in series
|
|
395
|
+
EgRef : float
|
|
396
|
+
effective band gap at STC [eV]
|
|
397
|
+
|
|
398
|
+
See also
|
|
399
|
+
--------
|
|
400
|
+
pvlib.pvsystem.calcparams_pvsyst
|
|
401
|
+
pvlib.ivtools.sdm.fit_pvsyst_sandia
|
|
402
|
+
|
|
403
|
+
Notes
|
|
404
|
+
-----
|
|
405
|
+
Input arrays of operating conditions and electrical measurements must be
|
|
406
|
+
1-D with equal lengths.
|
|
407
|
+
|
|
408
|
+
Values supplied for ``alpha_sc``, ``beta_mp``, and ``R_s`` must be
|
|
409
|
+
consistent with the matrix data, as these values are used when estimating
|
|
410
|
+
other model parameters.
|
|
411
|
+
|
|
412
|
+
This method is non-iterative. In some cases, it may be desirable to
|
|
413
|
+
refine the estimated parameter values using a numerical optimizer such as
|
|
414
|
+
the default method in ``scipy.optimize.minimize``.
|
|
415
|
+
|
|
416
|
+
References
|
|
417
|
+
----------
|
|
418
|
+
.. [1] K. S. Anderson, C. W. Hansen, and M. Theristis, "A Noniterative
|
|
419
|
+
Method of Estimating Parameter Values for the PVsyst Version 6
|
|
420
|
+
Single-Diode Model From IEC 61853-1 Matrix Measurements," IEEE Journal
|
|
421
|
+
of Photovoltaics, vol. 15, 3, 2025. :doi:`10.1109/JPHOTOV.2025.3554338`
|
|
422
|
+
"""
|
|
423
|
+
|
|
424
|
+
is_g_stc = np.isclose(effective_irradiance, 1000, rtol=0,
|
|
425
|
+
atol=irradiance_tolerance)
|
|
426
|
+
is_t_stc = np.isclose(temp_cell, 25, rtol=0,
|
|
427
|
+
atol=temperature_tolerance)
|
|
428
|
+
|
|
429
|
+
if alpha_sc is None:
|
|
430
|
+
mu_i_sc = _fit_tempco_pvsyst_iec61853_sandia_2025(i_sc[is_g_stc],
|
|
431
|
+
temp_cell[is_g_stc])
|
|
432
|
+
i_sc_ref = float(i_sc[is_g_stc & is_t_stc].item())
|
|
433
|
+
alpha_sc = mu_i_sc * i_sc_ref
|
|
434
|
+
|
|
435
|
+
if beta_mp is None:
|
|
436
|
+
beta_mp = _fit_tempco_pvsyst_iec61853_sandia_2025(v_mp[is_g_stc],
|
|
437
|
+
temp_cell[is_g_stc])
|
|
438
|
+
|
|
439
|
+
R_sh_ref, R_sh_0, R_sh_exp = \
|
|
440
|
+
_fit_shunt_resistances_pvsyst_iec61853_sandia_2025(
|
|
441
|
+
i_sc, i_mp, v_mp, effective_irradiance, temp_cell, beta_mp,
|
|
442
|
+
coeff=r_sh_coeff, min_irradiance=min_Rsh_irradiance)
|
|
443
|
+
|
|
444
|
+
if R_s is None:
|
|
445
|
+
R_s = _fit_series_resistance_pvsyst_iec61853_sandia_2025(v_oc, i_mp,
|
|
446
|
+
v_mp)
|
|
447
|
+
|
|
448
|
+
gamma_ref, mu_gamma = \
|
|
449
|
+
_fit_diode_ideality_factor_pvsyst_iec61853_sandia_2025(
|
|
450
|
+
i_sc[is_t_stc], v_oc[is_t_stc], i_mp[is_t_stc], v_mp[is_t_stc],
|
|
451
|
+
effective_irradiance[is_t_stc], temp_cell[is_t_stc],
|
|
452
|
+
R_sh_ref, R_sh_0, R_sh_exp, R_s, cells_in_series)
|
|
453
|
+
|
|
454
|
+
I_o_ref = _fit_saturation_current_pvsyst_iec61853_sandia_2025(
|
|
455
|
+
i_sc, v_oc, effective_irradiance, temp_cell, gamma_ref, mu_gamma,
|
|
456
|
+
R_sh_ref, R_sh_0, R_sh_exp, R_s, cells_in_series, EgRef
|
|
457
|
+
)
|
|
458
|
+
|
|
459
|
+
I_L_ref = _fit_photocurrent_pvsyst_iec61853_sandia_2025(
|
|
460
|
+
i_sc, effective_irradiance, temp_cell, alpha_sc,
|
|
461
|
+
gamma_ref, mu_gamma,
|
|
462
|
+
I_o_ref, R_sh_ref, R_sh_0, R_sh_exp, R_s, cells_in_series, EgRef
|
|
463
|
+
)
|
|
464
|
+
|
|
465
|
+
gamma_ref, mu_gamma = \
|
|
466
|
+
_fit_diode_ideality_factor_post_pvsyst_iec61853_sandia_2025(
|
|
467
|
+
i_mp, v_mp, effective_irradiance, temp_cell, alpha_sc, I_L_ref,
|
|
468
|
+
I_o_ref, R_sh_ref, R_sh_0, R_sh_exp, R_s, cells_in_series, EgRef)
|
|
469
|
+
|
|
470
|
+
fitted_params = dict(
|
|
471
|
+
alpha_sc=alpha_sc,
|
|
472
|
+
gamma_ref=gamma_ref,
|
|
473
|
+
mu_gamma=mu_gamma,
|
|
474
|
+
I_L_ref=I_L_ref,
|
|
475
|
+
I_o_ref=I_o_ref,
|
|
476
|
+
R_sh_ref=R_sh_ref,
|
|
477
|
+
R_sh_0=R_sh_0,
|
|
478
|
+
R_sh_exp=R_sh_exp,
|
|
479
|
+
R_s=R_s,
|
|
480
|
+
cells_in_series=cells_in_series,
|
|
481
|
+
EgRef=EgRef,
|
|
482
|
+
)
|
|
483
|
+
return fitted_params
|
|
484
|
+
|
|
485
|
+
|
|
486
|
+
def _fit_tempco_pvsyst_iec61853_sandia_2025(values, temp_cell,
|
|
487
|
+
temp_cell_ref=25):
|
|
488
|
+
fit = np.polynomial.polynomial.Polynomial.fit(temp_cell, values, deg=1)
|
|
489
|
+
intercept, slope = fit.convert().coef
|
|
490
|
+
value_ref = intercept + slope*temp_cell_ref
|
|
491
|
+
return slope / value_ref
|
|
492
|
+
|
|
493
|
+
|
|
494
|
+
def _fit_shunt_resistances_pvsyst_iec61853_sandia_2025(
|
|
495
|
+
i_sc, i_mp, v_mp, effective_irradiance, temp_cell,
|
|
496
|
+
beta_v_mp, coeff=0.2, min_irradiance=None):
|
|
497
|
+
if min_irradiance is None:
|
|
498
|
+
min_irradiance = 0
|
|
499
|
+
|
|
500
|
+
mask = effective_irradiance >= min_irradiance
|
|
501
|
+
i_sc = i_sc[mask]
|
|
502
|
+
i_mp = i_mp[mask]
|
|
503
|
+
v_mp = v_mp[mask]
|
|
504
|
+
effective_irradiance = effective_irradiance[mask]
|
|
505
|
+
temp_cell = temp_cell[mask]
|
|
506
|
+
|
|
507
|
+
# Equation 10
|
|
508
|
+
Rsh_est = (
|
|
509
|
+
(v_mp / (1 + beta_v_mp * (temp_cell - 25)))
|
|
510
|
+
/ (coeff * (i_sc - i_mp))
|
|
511
|
+
)
|
|
512
|
+
Rshexp = 5.5
|
|
513
|
+
|
|
514
|
+
# Eq 11
|
|
515
|
+
y = Rsh_est
|
|
516
|
+
x = np.exp(-Rshexp * effective_irradiance / 1000)
|
|
517
|
+
|
|
518
|
+
fit = np.polynomial.polynomial.Polynomial.fit(x, y, deg=1)
|
|
519
|
+
intercept, slope = fit.convert().coef
|
|
520
|
+
Rshbase = intercept
|
|
521
|
+
Rsh0 = slope + Rshbase
|
|
522
|
+
|
|
523
|
+
# Eq 12
|
|
524
|
+
expRshexp = np.exp(-Rshexp)
|
|
525
|
+
Rshref = Rshbase * (1 - expRshexp) + Rsh0 * expRshexp
|
|
526
|
+
|
|
527
|
+
return Rshref, Rsh0, Rshexp
|
|
528
|
+
|
|
529
|
+
|
|
530
|
+
def _fit_series_resistance_pvsyst_iec61853_sandia_2025(v_oc, i_mp, v_mp):
|
|
531
|
+
# Stein et al 2014, https://doi.org/10.1109/PVSC.2014.6925326
|
|
532
|
+
|
|
533
|
+
# Eq 13
|
|
534
|
+
x = np.array([np.ones(len(i_mp)), i_mp, np.log(i_mp), v_mp]).T
|
|
535
|
+
y = v_oc
|
|
536
|
+
|
|
537
|
+
coeff, _, _, _ = np.linalg.lstsq(x, y, rcond=None)
|
|
538
|
+
R_s = coeff[1]
|
|
539
|
+
return R_s
|
|
540
|
+
|
|
541
|
+
|
|
542
|
+
def _fit_diode_ideality_factor_pvsyst_iec61853_sandia_2025(
|
|
543
|
+
i_sc, v_oc, i_mp, v_mp, effective_irradiance, temp_cell,
|
|
544
|
+
R_sh_ref, R_sh_0, R_sh_exp, R_s, cells_in_series):
|
|
545
|
+
|
|
546
|
+
NsVth = _pvsyst_nNsVth(temp_cell, gamma=1, cells_in_series=cells_in_series)
|
|
547
|
+
Rsh = _pvsyst_Rsh(effective_irradiance, R_sh_ref, R_sh_0, R_sh_exp)
|
|
548
|
+
term1 = (i_sc * (1 + R_s/Rsh) - v_oc / Rsh) # Eq 15
|
|
549
|
+
term2 = (i_sc - i_mp) * (1 + R_s/Rsh) - v_mp / Rsh # Eq 16
|
|
550
|
+
|
|
551
|
+
# Eq 14
|
|
552
|
+
x1 = NsVth * np.log(term2 / term1)
|
|
553
|
+
|
|
554
|
+
x = np.array([x1]).T
|
|
555
|
+
y = v_mp + i_mp*R_s - v_oc
|
|
556
|
+
|
|
557
|
+
coeff, _, _, _ = np.linalg.lstsq(x, y, rcond=None)
|
|
558
|
+
gamma_ref = coeff[0]
|
|
559
|
+
return gamma_ref, 0
|
|
560
|
+
|
|
561
|
+
|
|
562
|
+
def _fit_saturation_current_pvsyst_iec61853_sandia_2025(
|
|
563
|
+
i_sc, v_oc, effective_irradiance, temp_cell, gamma_ref, mu_gamma,
|
|
564
|
+
R_sh_ref, R_sh_0, R_sh_exp, R_s, cells_in_series, EgRef):
|
|
565
|
+
R_sh = _pvsyst_Rsh(effective_irradiance, R_sh_ref, R_sh_0, R_sh_exp)
|
|
566
|
+
gamma = _pvsyst_gamma(temp_cell, gamma_ref, mu_gamma)
|
|
567
|
+
nNsVth = _pvsyst_nNsVth(temp_cell, gamma, cells_in_series)
|
|
568
|
+
|
|
569
|
+
# Eq 17
|
|
570
|
+
I_o_est = (i_sc * (1 + R_s/R_sh) - v_oc/R_sh) / (np.expm1(v_oc / nNsVth))
|
|
571
|
+
x = _pvsyst_Io(temp_cell, gamma, I_o_ref=1, EgRef=EgRef)
|
|
572
|
+
|
|
573
|
+
# Eq 18
|
|
574
|
+
log_I_o_ref = np.mean(np.log(I_o_est) - np.log(x))
|
|
575
|
+
I_o_ref = np.exp(log_I_o_ref)
|
|
576
|
+
|
|
577
|
+
return I_o_ref
|
|
578
|
+
|
|
579
|
+
|
|
580
|
+
def _fit_photocurrent_pvsyst_iec61853_sandia_2025(
|
|
581
|
+
i_sc, effective_irradiance, temp_cell, alpha_sc, gamma_ref,
|
|
582
|
+
mu_gamma, I_o_ref, R_sh_ref, R_sh_0, R_sh_exp, R_s, cells_in_series,
|
|
583
|
+
EgRef):
|
|
584
|
+
R_sh = _pvsyst_Rsh(effective_irradiance, R_sh_ref, R_sh_0, R_sh_exp)
|
|
585
|
+
gamma = _pvsyst_gamma(temp_cell, gamma_ref, mu_gamma)
|
|
586
|
+
I_o = _pvsyst_Io(temp_cell, gamma, I_o_ref, EgRef)
|
|
587
|
+
nNsVth = _pvsyst_nNsVth(temp_cell, gamma, cells_in_series)
|
|
588
|
+
|
|
589
|
+
# Eq 19
|
|
590
|
+
I_L_est = i_sc + I_o * (np.expm1(i_sc * R_s / nNsVth)) + i_sc * R_s / R_sh
|
|
591
|
+
|
|
592
|
+
# Eq 20
|
|
593
|
+
x = np.array([effective_irradiance / 1000]).T
|
|
594
|
+
y = I_L_est - effective_irradiance / 1000 * alpha_sc * (temp_cell - 25)
|
|
595
|
+
coeff, _, _, _ = np.linalg.lstsq(x, y, rcond=None)
|
|
596
|
+
I_L_ref = coeff[0]
|
|
597
|
+
return I_L_ref
|
|
598
|
+
|
|
599
|
+
|
|
600
|
+
def _fit_diode_ideality_factor_post_pvsyst_iec61853_sandia_2025(
|
|
601
|
+
i_mp, v_mp, effective_irradiance, temp_cell, alpha_sc, I_L_ref,
|
|
602
|
+
I_o_ref, R_sh_ref, R_sh_0, R_sh_exp, R_s, cells_in_series, EgRef):
|
|
603
|
+
|
|
604
|
+
Rsh = _pvsyst_Rsh(effective_irradiance, R_sh_ref, R_sh_0, R_sh_exp)
|
|
605
|
+
I_L = _pvsyst_IL(effective_irradiance, temp_cell, I_L_ref, alpha_sc)
|
|
606
|
+
NsVth = _pvsyst_nNsVth(temp_cell, gamma=1, cells_in_series=cells_in_series)
|
|
607
|
+
|
|
608
|
+
Tref_K = 25 + 273.15
|
|
609
|
+
Tcell_K = temp_cell + 273.15
|
|
610
|
+
|
|
611
|
+
# Eq 21
|
|
612
|
+
k = constants.k # Boltzmann constant in J/K
|
|
613
|
+
q = constants.e # elementary charge in coulomb
|
|
614
|
+
numerator = (
|
|
615
|
+
(q * EgRef / k) * (1/Tref_K - 1/Tcell_K)
|
|
616
|
+
+ (v_mp + i_mp*R_s) / NsVth
|
|
617
|
+
)
|
|
618
|
+
denominator = (
|
|
619
|
+
np.log((I_L - i_mp - (v_mp+i_mp*R_s) / Rsh) / I_o_ref)
|
|
620
|
+
- 3 * np.log(Tcell_K / Tref_K)
|
|
621
|
+
)
|
|
622
|
+
gamma_est = numerator / denominator
|
|
623
|
+
|
|
624
|
+
# Eq 22
|
|
625
|
+
x = np.array([np.ones(len(i_mp)), temp_cell - 25]).T
|
|
626
|
+
y = gamma_est
|
|
627
|
+
|
|
628
|
+
coeff, _, _, _ = np.linalg.lstsq(x, y, rcond=None)
|
|
629
|
+
gamma_ref, mu_gamma = coeff
|
|
630
|
+
return gamma_ref, mu_gamma
|