Skip to main content

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}