@@ -468,6 +468,9 @@ def snlinverter(self, v_dc, p_dc):
468
468
"""
469
469
return snlinverter (v_dc , p_dc , self .inverter_parameters )
470
470
471
+ def adrinverter (self , v_dc , p_dc ):
472
+ return adrinverter (v_dc , p_dc , self .inverter_parameters )
473
+
471
474
def scale_voltage_current_power (self , data ):
472
475
"""
473
476
Scales the voltage, current, and power of the DataFrames
@@ -1062,6 +1065,7 @@ def retrieve_sam(name=None, path=None):
1062
1065
* CEC module database
1063
1066
* Sandia Module database
1064
1067
* CEC Inverter database
1068
+ * Anton Driesse Inverter database
1065
1069
1066
1070
and return it as a pandas DataFrame.
1067
1071
@@ -1076,6 +1080,7 @@ def retrieve_sam(name=None, path=None):
1076
1080
(CEC is only current inverter db available; tag kept for
1077
1081
backwards compatibility)
1078
1082
* 'SandiaMod' - returns the Sandia Module database
1083
+ * 'ADRInverter' - returns the ADR Inverter database
1079
1084
1080
1085
path : None or string
1081
1086
Path to the SAM file. May also be a URL.
@@ -1128,6 +1133,8 @@ def retrieve_sam(name=None, path=None):
1128
1133
elif name == 'sandiamod' :
1129
1134
csvdata = os .path .join (
1130
1135
data_path , 'sam-library-sandia-modules-2015-6-30.csv' )
1136
+ elif name == 'adrinverter' :
1137
+ csvdata = os .path .join (data_path , 'adr-library-2013-10-01.csv' )
1131
1138
elif name in ['cecinverter' , 'sandiainverter' ]:
1132
1139
# Allowing either, to provide for old code,
1133
1140
# while aligning with current expectations
@@ -1177,6 +1184,13 @@ def _parse_raw_sam_df(csvdata):
1177
1184
1178
1185
df .index = parsedindex
1179
1186
df = df .transpose ()
1187
+ if 'ADRCoefficients' in df .index :
1188
+ ad_ce = 'ADRCoefficients'
1189
+ # for each inverter, parses a string of coefficients like
1190
+ # ' 1.33, 2.11, 3.12' into a list containing floats:
1191
+ # [1.33, 2.11, 3.12]
1192
+ df .loc [ad_ce ] = df .loc [ad_ce ].map (lambda x : list (
1193
+ map (float , x .strip (' []' ).split ())))
1180
1194
1181
1195
return df
1182
1196
@@ -2043,6 +2057,120 @@ def snlinverter(v_dc, p_dc, inverter):
2043
2057
return ac_power
2044
2058
2045
2059
2060
+ def adrinverter (v_dc , p_dc , inverter , vtol = 0.10 ):
2061
+ r'''
2062
+ Converts DC power and voltage to AC power using Anton Driesse's
2063
+ Grid-Connected PV Inverter efficiency model
2064
+
2065
+ Parameters
2066
+ ----------
2067
+ v_dc : numeric
2068
+ A scalar or pandas series of DC voltages, in volts, which are provided
2069
+ as input to the inverter. If Vdc and Pdc are vectors, they must be
2070
+ of the same size. v_dc must be >= 0. (V)
2071
+
2072
+ p_dc : numeric
2073
+ A scalar or pandas series of DC powers, in watts, which are provided
2074
+ as input to the inverter. If Vdc and Pdc are vectors, they must be
2075
+ of the same size. p_dc must be >= 0. (W)
2076
+
2077
+ inverter : dict-like
2078
+ A dict-like object defining the inverter to be used, giving the
2079
+ inverter performance parameters according to the model
2080
+ developed by Anton Driesse [1].
2081
+ A set of inverter performance parameters may be loaded from the
2082
+ supplied data table using retrievesam.
2083
+ See Notes for required keys.
2084
+
2085
+ vtol : numeric
2086
+ A unit-less fraction that determines how far the efficiency model is
2087
+ allowed to extrapolate beyond the inverter's normal input voltage
2088
+ operating range. 0.0 <= vtol <= 1.0
2089
+
2090
+ Returns
2091
+ -------
2092
+ ac_power : numeric
2093
+ A numpy array or pandas series of modeled AC power output given the
2094
+ input DC voltage, v_dc, and input DC power, p_dc. When ac_power would
2095
+ be greater than pac_max, it is set to p_max to represent inverter
2096
+ "clipping". When ac_power would be less than -p_nt (energy consumed
2097
+ rather than produced) then ac_power is set to -p_nt to represent
2098
+ nightly power losses. ac_power is not adjusted for maximum power point
2099
+ tracking (MPPT) voltage windows or maximum current limits of the
2100
+ inverter.
2101
+
2102
+ Notes
2103
+ -----
2104
+
2105
+ Required inverter keys are:
2106
+
2107
+ ======= ============================================================
2108
+ Column Description
2109
+ ======= ============================================================
2110
+ p_nom The nominal power value used to normalize all power values,
2111
+ typically the DC power needed to produce maximum AC power
2112
+ output, (W).
2113
+
2114
+ v_nom The nominal DC voltage value used to normalize DC voltage
2115
+ values, typically the level at which the highest efficiency
2116
+ is achieved, (V).
2117
+
2118
+ pac_max The maximum AC output power value, used to clip the output
2119
+ if needed, (W).
2120
+
2121
+ ce_list This is a list of 9 coefficients that capture the influence
2122
+ of input voltage and power on inverter losses, and thereby
2123
+ efficiency.
2124
+
2125
+ p_nt ac-power consumed by inverter at night (night tare) to
2126
+ maintain circuitry required to sense PV array voltage, (W).
2127
+ ======= ============================================================
2128
+
2129
+ References
2130
+ ----------
2131
+ [1] Beyond the Curves: Modeling the Electrical Efficiency
2132
+ of Photovoltaic Inverters, PVSC 2008, Anton Driesse et. al.
2133
+
2134
+ See also
2135
+ --------
2136
+ sapm
2137
+ singlediode
2138
+ '''
2139
+
2140
+ p_nom = inverter ['Pnom' ]
2141
+ v_nom = inverter ['Vnom' ]
2142
+ pac_max = inverter ['Pacmax' ]
2143
+ p_nt = inverter ['Pnt' ]
2144
+ ce_list = inverter ['ADRCoefficients' ]
2145
+ v_max = inverter ['Vmax' ]
2146
+ v_min = inverter ['Vmin' ]
2147
+ vdc_max = inverter ['Vdcmax' ]
2148
+ mppt_hi = inverter ['MPPTHi' ]
2149
+ mppt_low = inverter ['MPPTLow' ]
2150
+
2151
+ v_lim_upper = np .nanmax ([v_max , vdc_max , mppt_hi ])* (1 + vtol )
2152
+ v_lim_lower = np .nanmax ([v_min , mppt_low ])* (1 - vtol )
2153
+
2154
+ pdc = p_dc / p_nom
2155
+ vdc = v_dc / v_nom
2156
+ poly = np .array ([pdc ** 0 , pdc , pdc ** 2 , vdc - 1 , pdc * (vdc - 1 ),
2157
+ pdc ** 2 * (vdc - 1 ), 1 / vdc - 1 , pdc * (1. / vdc - 1 ),
2158
+ pdc ** 2 * (1. / vdc - 1 )])
2159
+ p_loss = np .dot (np .array (ce_list ), poly )
2160
+ ac_power = p_nom * (pdc - p_loss )
2161
+ p_nt = - 1 * np .absolute (p_nt )
2162
+
2163
+ ac_power = np .where ((v_lim_upper < v_dc ) | (v_dc < v_lim_lower ),
2164
+ np .nan , ac_power )
2165
+ ac_power = np .where ((ac_power < p_nt ) | (vdc == 0 ), p_nt , ac_power )
2166
+ ac_power = np .where (ac_power > pac_max , pac_max , ac_power )
2167
+
2168
+ if isinstance (p_dc , pd .Series ):
2169
+ ac_power = pd .Series (ac_power , index = pdc .index )
2170
+
2171
+ return ac_power
2172
+
2173
+
2046
2174
def scale_voltage_current_power (data , voltage = 1 , current = 1 ):
2047
2175
"""
2048
2176
Scales the voltage, current, and power of the DataFrames
0 commit comments