1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
/// Simplified soiling loss mass accumulation model (inspired by Hsu et al).
///
/// Estimates daily soiling accumulation based on particulate matter concentrations,
/// assuming natural rain washing.
///
/// # Arguments
/// * `rainfall` - Daily rainfall in mm.
/// * `cleaning_threshold` - Rainfall threshold to clean the panels (e.g., 5.0 mm).
/// * `tilt` - Surface tilt in degrees.
/// * `pm2_5` - PM 2.5 concentration in ug/m^3.
/// * `pm10` - PM 10 concentration in ug/m^3.
///
/// # Returns
/// Soiling mass accumulation fraction for the day.
/// HSU soiling model - single timestep mass accumulation update.
///
/// Computes the soiling ratio using the Fixed Velocity model from Humboldt State
/// University (HSU). The soiling ratio ranges from 0 to 1, where 1 means no soiling.
///
/// This is a single-timestep function. To simulate over time, accumulate mass across
/// timesteps, resetting to 0 when rainfall exceeds the cleaning threshold, then
/// convert accumulated mass to soiling ratio with `hsu_soiling_ratio`.
///
/// # Arguments
/// * `pm2_5` - PM2.5 concentration [g/m^3].
/// * `pm10` - PM10 concentration [g/m^3].
/// * `depo_veloc_2_5` - Deposition velocity for PM2.5 [m/s], default 0.0009.
/// * `depo_veloc_10` - Deposition velocity for PM10 [m/s], default 0.004.
/// * `surface_tilt` - Module tilt from horizontal [degrees].
/// * `dt_sec` - Timestep duration [seconds].
///
/// # Returns
/// Mass deposited on the tilted surface during this timestep [g/m^2].
///
/// # References
/// Coello, M. and Boyle, L. (2019). "Simple Model For Predicting Time Series
/// Soiling of Photovoltaic Panels." IEEE Journal of Photovoltaics.
/// Converts accumulated soiling mass to a soiling ratio using the HSU model.
///
/// soiling_ratio = 1 - 0.3437 * erf(0.17 * accum_mass^0.8473)
///
/// # Arguments
/// * `accumulated_mass` - Total accumulated soiling mass on the surface [g/m^2].
///
/// # Returns
/// Soiling ratio (0 to 1), where 1 means perfectly clean.
/// HSU soiling model convenience function for a single timestep.
///
/// Returns the soiling ratio given current accumulated mass and whether
/// rainfall has cleaned the panels.
///
/// # Arguments
/// * `rainfall` - Rainfall accumulated in the current period [mm].
/// * `cleaning_threshold` - Rainfall needed to clean panels [mm].
/// * `surface_tilt` - Module tilt [degrees].
/// * `pm2_5` - PM2.5 concentration [g/m^3].
/// * `pm10` - PM10 concentration [g/m^3].
/// * `depo_veloc_2_5` - PM2.5 deposition velocity [m/s], default 0.0009.
/// * `depo_veloc_10` - PM10 deposition velocity [m/s], default 0.004.
/// * `dt_sec` - Timestep duration [seconds].
/// * `previous_mass` - Accumulated mass from previous timestep [g/m^2].
///
/// # Returns
/// A tuple of (soiling_ratio, new_accumulated_mass).
/// Kimber soiling model - single timestep update.
///
/// Linear soiling accumulation with rain cleaning resets. Soiling builds up
/// at a daily rate unless rainfall exceeds the cleaning threshold.
///
/// # Arguments
/// * `rainfall` - Rainfall accumulated in the current period [mm].
/// * `cleaning_threshold` - Daily rainfall needed to clean panels [mm], default 6.0.
/// * `soiling_loss_rate` - Fraction of energy lost per day of soiling [unitless], default 0.0015.
/// * `max_soiling` - Maximum soiling loss fraction [unitless], default 0.3.
/// * `timestep_days` - Duration of the current timestep as a fraction of a day.
/// * `previous_soiling` - Soiling loss from previous timestep (0 to max_soiling).
/// * `is_grace_period` - True if within the grace period after a rain event (ground too damp for soiling).
///
/// # Returns
/// Updated soiling loss fraction (0.0 to max_soiling).
///
/// # References
/// Kimber, A. et al. (2006). "The Effect of Soiling on Large Grid-Connected
/// Photovoltaic Systems in California and the Southwest Region of the United States."
/// IEEE 4th World Conference on Photovoltaic Energy Conference.
/// Approximate error function using Abramowitz and Stegun formula 7.1.26.
/// Maximum error ~1.5e-7.