pvlib/pvarray.rs
1/// Calculate PV module efficiency using the ADR model.
2///
3/// The efficiency varies with irradiance and operating temperature
4/// and is determined by 5 model parameters (Driesse et al., 2020).
5///
6/// # Arguments
7/// * `effective_irradiance` - Effective irradiance on PV module in W/m^2.
8/// * `temp_cell` - PV module operating temperature in degrees C.
9/// * `k_a` - Absolute scaling factor (efficiency at reference conditions).
10/// * `k_d` - Dark irradiance / diode coefficient (negative).
11/// * `tc_d` - Temperature coefficient of diode coefficient.
12/// * `k_rs` - Series resistance loss coefficient.
13/// * `k_rsh` - Shunt resistance loss coefficient.
14///
15/// # Returns
16/// Module efficiency (same units/scale as k_a).
17#[inline]
18pub fn pvefficiency_adr(
19 effective_irradiance: f64,
20 temp_cell: f64,
21 k_a: f64,
22 k_d: f64,
23 tc_d: f64,
24 k_rs: f64,
25 k_rsh: f64,
26) -> f64 {
27 let g_ref = 1000.0;
28 let t_ref = 25.0;
29
30 let s = effective_irradiance / g_ref;
31 let dt = temp_cell - t_ref;
32
33 // Eq 29: s_o and s_o_ref using 10^x
34 let s_o = 10.0_f64.powf(k_d + dt * tc_d);
35 let s_o_ref = 10.0_f64.powf(k_d);
36
37 // Eq 28, 30: normalized voltage
38 let v = (s / s_o + 1.0).ln() / (1.0 / s_o_ref + 1.0).ln();
39
40 // Eq 25: efficiency
41 k_a * ((1.0 + k_rs + k_rsh) * v - k_rs * s - k_rsh * v * v)
42}
43
44/// DC power using the Huld model (used by PVGIS).
45///
46/// P_dc = G' * (pdc0 + k1*ln(G') + k2*ln(G')^2 + k3*T' + k4*T'*ln(G') + k5*T'*ln(G')^2 + k6*T'^2)
47///
48/// where G' = irradiance/1000, T' = temp_module - 25.
49///
50/// # Arguments
51/// * `effective_irradiance` - Irradiance converted to photocurrent in W/m^2.
52/// * `temp_module` - Module back-surface temperature in degrees C.
53/// * `pdc0` - Power at reference conditions (1000 W/m^2, 25C) in W.
54/// * `k` - Six empirical coefficients [k1, k2, k3, k4, k5, k6].
55///
56/// # Returns
57/// DC power in W.
58#[inline]
59pub fn huld(
60 effective_irradiance: f64,
61 temp_module: f64,
62 pdc0: f64,
63 k: [f64; 6],
64) -> f64 {
65 let gprime = effective_irradiance / 1000.0;
66 let tprime = temp_module - 25.0;
67
68 let log_g = if gprime > 0.0 { gprime.ln() } else { 0.0 };
69
70 gprime
71 * (pdc0
72 + k[0] * log_g
73 + k[1] * log_g * log_g
74 + k[2] * tprime
75 + k[3] * tprime * log_g
76 + k[4] * tprime * log_g * log_g
77 + k[5] * tprime * tprime)
78}