@@ -191,6 +191,11 @@ def __init__(self,
191
191
racking_model = None , losses_parameters = None , name = None ):
192
192
193
193
if arrays is None :
194
+ if losses_parameters is None :
195
+ array_losses_parameters = {}
196
+ else :
197
+ array_losses_parameters = _build_kwargs (['dc_ohmic_percent' ],
198
+ losses_parameters )
194
199
self .arrays = (Array (
195
200
surface_tilt ,
196
201
surface_azimuth ,
@@ -202,7 +207,8 @@ def __init__(self,
202
207
temperature_model_parameters ,
203
208
modules_per_string ,
204
209
strings_per_inverter ,
205
- racking_model
210
+ racking_model ,
211
+ array_losses_parameters ,
206
212
),)
207
213
else :
208
214
self .arrays = tuple (arrays )
@@ -1092,6 +1098,17 @@ def pvwatts_ac(self, pdc):
1092
1098
return inverter .pvwatts (pdc , self .inverter_parameters ['pdc0' ],
1093
1099
** kwargs )
1094
1100
1101
+ @_unwrap_single_value
1102
+ def dc_ohms_from_percent (self ):
1103
+ """
1104
+ Calculates the equivalent resistance of the wires for each array using
1105
+ :py:func:`pvlib.pvsystem.dc_ohms_from_percent`
1106
+
1107
+ See :py:func:`pvlib.pvsystem.dc_ohms_from_percent` for details.
1108
+ """
1109
+
1110
+ return tuple (array .dc_ohms_from_percent () for array in self .arrays )
1111
+
1095
1112
@property
1096
1113
@_unwrap_single_value
1097
1114
def module_parameters (self ):
@@ -1224,6 +1241,9 @@ class Array:
1224
1241
Valid strings are 'open_rack', 'close_mount', and 'insulated_back'.
1225
1242
Used to identify a parameter set for the SAPM cell temperature model.
1226
1243
1244
+ array_losses_parameters: None, dict or Series, default None.
1245
+ Supported keys are 'dc_ohmic_percent'.
1246
+
1227
1247
"""
1228
1248
1229
1249
def __init__ (self ,
@@ -1233,7 +1253,8 @@ def __init__(self,
1233
1253
module_parameters = None ,
1234
1254
temperature_model_parameters = None ,
1235
1255
modules_per_string = 1 , strings = 1 ,
1236
- racking_model = None , name = None ):
1256
+ racking_model = None , array_losses_parameters = None ,
1257
+ name = None ):
1237
1258
self .surface_tilt = surface_tilt
1238
1259
self .surface_azimuth = surface_azimuth
1239
1260
@@ -1261,6 +1282,11 @@ def __init__(self,
1261
1282
else :
1262
1283
self .temperature_model_parameters = temperature_model_parameters
1263
1284
1285
+ if array_losses_parameters is None :
1286
+ self .array_losses_parameters = {}
1287
+ else :
1288
+ self .array_losses_parameters = array_losses_parameters
1289
+
1264
1290
self .name = name
1265
1291
1266
1292
def __repr__ (self ):
@@ -1447,6 +1473,72 @@ def get_iam(self, aoi, iam_model='physical'):
1447
1473
else :
1448
1474
raise ValueError (model + ' is not a valid IAM model' )
1449
1475
1476
+ def dc_ohms_from_percent (self ):
1477
+ """
1478
+ Calculates the equivalent resistance of the wires using
1479
+ :py:func:`pvlib.pvsystem.dc_ohms_from_percent`
1480
+
1481
+ Makes use of array module parameters according to the
1482
+ following DC models:
1483
+
1484
+ CEC:
1485
+
1486
+ * `self.module_parameters["V_mp_ref"]`
1487
+ * `self.module_parameters["I_mp_ref"]`
1488
+
1489
+ SAPM:
1490
+
1491
+ * `self.module_parameters["Vmpo"]`
1492
+ * `self.module_parameters["Impo"]`
1493
+
1494
+ PVsyst-like or other:
1495
+
1496
+ * `self.module_parameters["Vmpp"]`
1497
+ * `self.module_parameters["Impp"]`
1498
+
1499
+ Other array parameters that are used are:
1500
+ `self.losses_parameters["dc_ohmic_percent"]`,
1501
+ `self.modules_per_string`, and
1502
+ `self.strings`.
1503
+
1504
+ See :py:func:`pvlib.pvsystem.dc_ohms_from_percent` for more details.
1505
+ """
1506
+
1507
+ # get relevent Vmp and Imp parameters from CEC parameters
1508
+ if all ([elem in self .module_parameters
1509
+ for elem in ['V_mp_ref' , 'I_mp_ref' ]]):
1510
+ vmp_ref = self .module_parameters ['V_mp_ref' ]
1511
+ imp_ref = self .module_parameters ['I_mp_ref' ]
1512
+
1513
+ # get relevant Vmp and Imp parameters from SAPM parameters
1514
+ elif all ([elem in self .module_parameters
1515
+ for elem in ['Vmpo' , 'Impo' ]]):
1516
+ vmp_ref = self .module_parameters ['Vmpo' ]
1517
+ imp_ref = self .module_parameters ['Impo' ]
1518
+
1519
+ # get relevant Vmp and Imp parameters if they are PVsyst-like
1520
+ elif all ([elem in self .module_parameters
1521
+ for elem in ['Vmpp' , 'Impp' ]]):
1522
+ vmp_ref = self .module_parameters ['Vmpp' ]
1523
+ imp_ref = self .module_parameters ['Impp' ]
1524
+
1525
+ # raise error if relevant Vmp and Imp parameters are not found
1526
+ else :
1527
+ raise ValueError ('Parameters for Vmp and Imp could not be found '
1528
+ 'in the array module parameters. Module '
1529
+ 'parameters must include one set of '
1530
+ '{"V_mp_ref", "I_mp_Ref"}, '
1531
+ '{"Vmpo", "Impo"}, or '
1532
+ '{"Vmpp", "Impp"}.'
1533
+ )
1534
+
1535
+ return dc_ohms_from_percent (
1536
+ vmp_ref ,
1537
+ imp_ref ,
1538
+ self .array_losses_parameters ['dc_ohmic_percent' ],
1539
+ self .modules_per_string ,
1540
+ self .strings )
1541
+
1450
1542
1451
1543
def calcparams_desoto (effective_irradiance , temp_cell ,
1452
1544
alpha_sc , a_ref , I_L_ref , I_o_ref , R_sh_ref , R_s ,
@@ -2885,6 +2977,80 @@ def pvwatts_losses(soiling=2, shading=3, snow=0, mismatch=2, wiring=2,
2885
2977
return losses
2886
2978
2887
2979
2980
+ def dc_ohms_from_percent (vmp_ref , imp_ref , dc_ohmic_percent ,
2981
+ modules_per_string = 1 ,
2982
+ strings = 1 ):
2983
+ """
2984
+ Calculates the equivalent resistance of the wires from a percent
2985
+ ohmic loss at STC.
2986
+
2987
+ Equivalent resistance is calculated with the function:
2988
+
2989
+ .. math::
2990
+ Rw = (L_{stc} / 100) * (Varray / Iarray)
2991
+
2992
+ :math:`Rw` is the equivalent resistance in ohms
2993
+ :math:`Varray` is the Vmp of the modules times modules per string
2994
+ :math:`Iarray` is the Imp of the modules times strings per array
2995
+ :math:`L_{stc}` is the input dc loss percent
2996
+
2997
+ Parameters
2998
+ ----------
2999
+ vmp_ref: numeric
3000
+ Voltage at maximum power in reference conditions [V]
3001
+ imp_ref: numeric
3002
+ Current at maximum power in reference conditions [V]
3003
+ dc_ohmic_percent: numeric, default 0
3004
+ input dc loss as a percent, e.g. 1.5% loss is input as 1.5
3005
+ modules_per_string: int, default 1
3006
+ Number of modules per string in the array.
3007
+ strings: int, default 1
3008
+ Number of parallel strings in the array.
3009
+
3010
+ Returns
3011
+ ----------
3012
+ Rw: numeric
3013
+ Equivalent resistance [ohm]
3014
+
3015
+ References
3016
+ ----------
3017
+ .. [1] PVsyst 7 Help. "Array ohmic wiring loss".
3018
+ https://www.pvsyst.com/help/ohmic_loss.htm
3019
+ """
3020
+ vmp = modules_per_string * vmp_ref
3021
+
3022
+ imp = strings * imp_ref
3023
+
3024
+ Rw = (dc_ohmic_percent / 100 ) * (vmp / imp )
3025
+
3026
+ return Rw
3027
+
3028
+
3029
+ def dc_ohmic_losses (resistance , current ):
3030
+ """
3031
+ Returns ohmic losses in units of power from the equivalent
3032
+ resistance of the wires and the operating current.
3033
+
3034
+ Parameters
3035
+ ----------
3036
+ resistance: numeric
3037
+ Equivalent resistance of wires [ohm]
3038
+ current: numeric, float or array-like
3039
+ Operating current [A]
3040
+
3041
+ Returns
3042
+ ----------
3043
+ loss: numeric
3044
+ Power Loss [W]
3045
+
3046
+ References
3047
+ ----------
3048
+ .. [1] PVsyst 7 Help. "Array ohmic wiring loss".
3049
+ https://www.pvsyst.com/help/ohmic_loss.htm
3050
+ """
3051
+ return resistance * current * current
3052
+
3053
+
2888
3054
def combine_loss_factors (index , * losses , fill_method = 'ffill' ):
2889
3055
r"""
2890
3056
Combines Series loss fractions while setting a common index.
0 commit comments