@@ -186,19 +186,31 @@ bool mlmodel_module_t::operator() (pvinput_t &input, double T_C, double opvoltag
186186 }
187187
188188 // Total effective irradiance
189- double S ;
189+ double S_front, S_total, S_eff_front, S_eff_total ;
190190 if (input.radmode != 3 ){ // Skip module cover effects if using POA reference cell data
191- S = (f_IAM_beam * input.Ibeam + f_IAM_diff * input.Idiff + groundRelfectionFraction * f_IAM_gnd * input.Ignd ) * f_AM;
191+ S_front = input.Ibeam + input.Idiff + input.Ignd ;
192+ S_total = S_front + input.Irear ; // Note the rear irradiance has already taken bifaciality into consideration
193+ S_eff_front = (f_IAM_beam * input.Ibeam + f_IAM_diff * input.Idiff + groundRelfectionFraction * f_IAM_gnd * input.Ignd ) * f_AM;
194+ S_eff_total = S_eff_front + input.Irear * f_AM;
195+ if (S_front > 1e-8 ) { // TODO: should sunup catch this?
196+ out.AOIModifier = S_eff_front / S_front;
197+ }
198+ else {
199+ out.AOIModifier = 1.0 ;
200+ }
192201 }
193202 else if (input.usePOAFromWF ){ // Check if decomposed POA is required, if not use weather file POA directly
194- S = input.poaIrr ;
203+ S_total = S_eff_total = input.poaIrr ;
204+ out.AOIModifier = 1.0 ;
195205 }
196206 else { // Otherwise use decomposed POA
197- S = (f_IAM_beam * input.Ibeam + f_IAM_diff * input.Idiff + groundRelfectionFraction * f_IAM_gnd * input.Ignd ) * f_AM;
207+ S_total = input.poaIrr ;
208+ S_eff_total = input.Ibeam + input.Idiff + input.Ignd + input.Irear ;
209+ out.AOIModifier = 1.0 ;
198210 }
199211
200212 // Single diode model acc. to [1]
201- if (S >= 1 )
213+ if (S_eff_total >= 1 )
202214 {
203215 double n=0.0 , a=0.0 , I_L=0.0 , I_0=0.0 , R_sh=0.0 , I_sc=0.0 ;
204216 double V_oc = V_oc_ref; // V_oc_ref as initial guess
@@ -217,16 +229,16 @@ bool mlmodel_module_t::operator() (pvinput_t &input, double T_C, double opvoltag
217229 for (int i = 1 ; i <= iterations; i = i + 1 ) {
218230 if (T_mode == T_MODE_FAIMAN) {
219231 // T_cell = input.Tdry + (T_c_fa_alpha * G_total * (1 - eff)) / (T_c_fa_U0 + input.Wspd * T_c_fa_U1);
220- T_cell = input.Tdry + (T_c_fa_alpha * S * (1 - eff)) / (T_c_fa_U0 + input.Wspd * T_c_fa_U1);
232+ T_cell = input.Tdry + (T_c_fa_alpha * S_eff_total * (1 - eff)) / (T_c_fa_U0 + input.Wspd * T_c_fa_U1);
221233 }
222234
223235 n = n_0 + mu_n * (T_cell - T_ref);
224236 a = N_series * k * (T_cell + T_0) * n / q;
225- I_L = (S / S_ref) * (I_Lref + alpha_isc * (T_cell - T_ref));
226- // I_L = (S / S_ref) * (I_Lref + alpha_isc / N_parallel * (T_cell - T_ref));
237+ I_L = (S_eff_total / S_ref) * (I_Lref + alpha_isc * (T_cell - T_ref));
238+ // I_L = (S_eff_total / S_ref) * (I_Lref + alpha_isc / N_parallel * (T_cell - T_ref));
227239 I_0 = I_0ref * pow (((T_cell + T_0) / (T_ref + T_0)), 3 ) * exp ((q * E_g) / (n * k) * (1 / (T_ref + T_0) - 1 / (T_cell + T_0)));
228240
229- R_sh = R_shref + (R_sh0 - R_shref) * exp (-R_shexp * (S / S_ref));
241+ R_sh = R_shref + (R_sh0 - R_shref) * exp (-R_shexp * (S_eff_total / S_ref));
230242
231243 V_oc = openvoltage_5par_rec (V_oc, a, I_L, I_0, R_sh, D2MuTau, Vbi);
232244 I_sc = I_L / (1 + R_s / R_sh);
@@ -243,7 +255,7 @@ bool mlmodel_module_t::operator() (pvinput_t &input, double T_C, double opvoltag
243255 else I = current_5par_rec (V, 0.9 *I_L, a, I_L, I_0, R_s, R_sh, D2MuTau, Vbi);
244256 P = V*I;
245257 }
246- eff = P / ((Width * Length) * (input. Ibeam + input. Idiff + input. Ignd ) );
258+ eff = P / ((Width * Length) * S_total );
247259 }
248260
249261 out.Power = P;
@@ -253,7 +265,6 @@ bool mlmodel_module_t::operator() (pvinput_t &input, double T_C, double opvoltag
253265 out.Voc_oper = V_oc;
254266 out.Isc_oper = I_sc;
255267 out.CellTemp = T_cell;
256- out.AOIModifier = S / (input.Ibeam + input.Idiff + input.Ignd );
257268 }
258269
259270 return out.Power >= 0 ;
0 commit comments