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
/// Simplified Townsend snow model for PV systems.
///
/// Predicts whether snow slides off the array based on temperature and tilt.
///
/// # Arguments
/// * `tilt` - Surface tilt in degrees.
/// * `temperature` - Ambient or module temperature in Celsius.
/// * `poa_global` - Plane of array global irradiance (W/m^2).
///
/// # Returns
/// True if conditions are correct for snow to slide off.
/// Marion snow model.
///
/// Evaluates sliding properties based on complex surface depth thresholds.
///
/// # References
/// Marion, B. et al., 2013, "Measured and modeled photovoltaic system energy losses from snow."
/// Determines whether a module is fully covered by snow based on snowfall rate.
///
/// Returns true when the snowfall rate exceeds the threshold, indicating
/// the module is fully covered.
///
/// # Arguments
/// * `snowfall` - Snowfall in the time period [cm].
/// * `timestep_hours` - Duration of the time period [hours].
/// * `threshold_snowfall` - Hourly snowfall threshold for full coverage [cm/hr], default 1.0.
///
/// # Returns
/// True if the module is fully covered by snow.
///
/// # References
/// Marion, B. et al. (2013). "Measured and modeled photovoltaic system
/// energy losses from snow for Colorado and Wisconsin locations." Solar Energy 97, pp.112-121.
/// Calculates the fraction of a module row's slant height covered by snow,
/// after accounting for sliding.
///
/// This is a single-timestep update function. To simulate over time, call
/// repeatedly, passing the returned coverage as `previous_coverage` for the next step.
///
/// # Arguments
/// * `snowfall` - Snowfall in the current time period [cm].
/// * `poa_irradiance` - Plane-of-array irradiance [W/m^2].
/// * `temp_air` - Ambient air temperature [C].
/// * `surface_tilt` - Module tilt from horizontal [degrees].
/// * `previous_coverage` - Snow coverage fraction from previous timestep (0-1).
/// * `timestep_hours` - Duration of the time period [hours].
/// * `threshold_snowfall` - Hourly snowfall threshold for full coverage [cm/hr], default 1.0.
/// * `can_slide_coefficient` - Coefficient for slide condition [W/(m^2 C)], default -80.0.
/// * `slide_amount_coefficient` - Fraction of snow sliding per hour, default 0.197.
///
/// # Returns
/// Updated snow coverage fraction (0.0 to 1.0).
///
/// # References
/// Marion, B. et al. (2013). "Measured and modeled photovoltaic system
/// energy losses from snow." Solar Energy 97, pp.112-121.
/// Calculates the fraction of DC capacity lost due to snow coverage on strings.
///
/// Assumes that if any part of a string is covered, the entire string's output is lost.
/// The loss fraction is ceil(coverage * num_strings) / num_strings.
///
/// # Arguments
/// * `snow_coverage` - Fraction of row slant height covered by snow (0-1).
/// * `num_strings` - Number of parallel-connected cell strings along the slant height.
///
/// # Returns
/// Fraction of DC capacity lost (0.0 to 1.0).
///
/// # References
/// Gilman, P. et al. (2018). "SAM Photovoltaic Model Technical Reference Update",
/// NREL/TP-6A20-67399.