Soil Water Balance (SWB2)
Loading...
Searching...
No Matches
summary_statistics.F90
Go to the documentation of this file.
2
3 use iso_c_binding
4 use exceptions
7 use fstring
9 implicit none
10
13
14 integer (c_int) :: lu
15 character (len=1), parameter :: tab = achar(9)
16
17 logical (c_bool) :: anything_to_summarize = false
18
19contains
20
21 subroutine add_polygon_id_to_summary_list( polygon_id )
22
23 call poly_id%append( polygon_id )
25
27
28!-------------------------------------------------------------------------------
29
30 subroutine add_landuse_code_to_summary_list( landuse_code )
31
32 call landuse_codes%append( landuse_code )
34
36
37!-------------------------------------------------------------------------------
38
40
41 ! [ LOCALS ]
42 integer (c_int) :: status
43 character (len=256) :: fname
44
45 if ( anything_to_summarize ) then
46
47 fname="Daily_SWB2_summary_statistics.txt"
48 open( newunit=lu, file=fname )
49
50 write( lu, "(256a)") "Date", tab, "POLY_ID", tab, "count", tab, "lc", &
51 tab, "sms_max", tab, "rain", tab, "fog", tab, "irr", tab, "runoff", tab, &
52 "can_evap", tab, "ref_et0", tab, "crop_et0", tab, "actual_et", tab, &
53 "recharge", tab, "sms_end", tab, "surface_storage_excess", tab, &
54 "surface_storage", tab, "snowmelt", tab, "impervious_fraction", &
55 tab, "actual_et_soil"
56
57 endif
58
60
61!--------------------------------------------------------------------------------------------------
62
63 subroutine perform_summary_statistics( cells )
64
65 type ( MODEL_DOMAIN_T ), intent(inout) :: cells
66
67 if ( anything_to_summarize ) then
68
69 if ( poly_id%count > 0 ) call summarize_by_polygon( cells )
70
71 if ( landuse_codes%count > 0 ) call summarize_by_landuse( cells )
72
73 endif
74
75 end subroutine perform_summary_statistics
76
77!-------------------------------------------------------------------------------
78
79 subroutine summarize_by_polygon( cells )
80
81 type ( MODEL_DOMAIN_T ), intent(inout) :: cells
82
83 ! [ LOCALS ]
84 integer (c_int) :: indx
85 logical :: belongs_to_poly( ubound( cells%polygon_id, 1 ) )
86
87 do indx=1, ubound( poly_id, 1 )
88
89 ! identify the cells that belong to this polygon id
90 belongs_to_poly = ( cells%polygon_id == poly_id( indx ) )
91 call write_out_values( cell_selection=belongs_to_poly )
92
93 enddo
94
95 end subroutine summarize_by_polygon
96
97 !-------------------------------------------------------------------------------
98
99 subroutine summarize_by_landuse( cells )
100
101 type ( MODEL_DOMAIN_T ), intent(inout) :: cells
102
103 ! [ LOCALS ]
104 logical :: belongs_to_lu( ubound( cells%landuse_code, 1 ) )
105 integer (c_int) :: indx
106
107 do indx=1, ubound( landuse_code_list, 1 )
108
109 ! identify the cells that belong to this polygon id
110 belongs_to_lu = ( cells%landuse_code == landuse_code_list( indx ) )
111 call write_out_values( cell_selection=belongs_to_lu )
112
113 enddo
114
115 end subroutine summarize_by_landuse
116
117!-------------------------------------------------------------------------------
118
119 subroutine write_out_values( cell_selection, poly_id )
120
121 logical (c_bool), intent(in) :: cell_selection(:)
122 integer (c_int), intent(in), optional :: poly_id
123
124 integer (c_int) :: lc
125 integer (c_int) :: poly_id_l
126 character (len=10) :: date
127 real (c_float) :: sms_max, rain, fog, irr, runoff, can_evap, ref_et0, &
128 crop_et0, actual_et, recharge, sms_end, snowmelt, &
129 surface_storage_excess, impervious_frac, surface_storage, &
130 actual_et_soil
131
132 if ( present(poly_id) ) then
133
134 poly_id_l = poly_id
135
136 else
137
138 poly_id_l = -999
139
140 endif
141
142 date = sim_dt%curr%prettydate()
143
144 lc = most_common_value( cells%landuse_code, cell_selection )
145 sms_max = mean( cells%soil_storage_max, cell_selection )
146 rain = mean( cells%rainfall, cell_selection )
147 fog = mean( cells%fog, cell_selection )
148 irr = mean( cells%irrigation, cell_selection )
149 runoff = mean( cells%runoff, cell_selection )
150 can_evap = mean( cells%interception, cell_selection )
151 ref_et0 = mean( cells%reference_et0, cell_selection )
152 crop_et0 = mean( cells%reference_et0 * cells%crop_coefficient_kcb, cell_selection )
153 actual_et_soil = mean( real( cells%actual_et_soil, c_float), cell_selection )
154 actual_et = mean( real( cells%actual_et, c_float), cell_selection )
155 recharge = mean( cells%net_infiltration, cell_selection )
156 sms_end = mean( cells%soil_storage, cell_selection )
157 surface_storage_excess = mean( cells%surface_storage_excess, cell_selection )
158 surface_storage = mean( cells%surface_storage, cell_selection )
159 snowmelt = mean( cells%snowmelt, cell_selection )
160 impervious_frac = 1.0_c_float - mean( cells%pervious_fraction, cell_selection )
161
162 write( unit=lu, fmt="(2a,3(i0,a),15(f12.3,a),f12.3)" ) &
163 date, tab, &
164 poly_id_l, tab, count( cell_selection), tab, lc, tab, &
165 sms_max, tab, rain, tab, fog, tab, &
166 irr, tab, runoff, tab, can_evap, tab, ref_et0, tab, crop_et0, tab, &
167 actual_et, tab, recharge, tab, sms_end, tab, surface_storage_excess, &
168 tab, surface_storage, tab, snowmelt, tab, impervious_frac, &
169 tab, actual_et_soil
170
171 flush( unit=lu )
172
173 end subroutine write_out_values
174
175!--------------------------------------------------------------------------------------------------
176
177 function most_common_value( int_vector, cell_selection ) result( majority_value )
178
179 integer ( c_int) :: int_vector(:)
180 logical :: cell_selection(:)
181
182 ! [ LOCALS ]
183 integer (c_int), dimension(625) :: value
184 integer (c_int), dimension(625) :: item_count
185 logical :: match
186 integer (c_int) :: index, index1, index2
187 integer (c_int) :: last
188 integer (c_int) :: majority_value
189
190 value = 0
191 item_count = 0
192 last = 0
193
194 do index1=1, ubound( int_vector, 1 )
195
196 ! skip over cells that do not belong to the current polygon
197 if ( .not. cell_selection( index1 ) ) cycle
198
199 match = .false.
200
201 ! loop over the items we have already found; if we found another,
202 ! add to the count of that item
203 do index2=1, last
204 if (value(index2) == int_vector( index1 ) ) then
205 item_count( index2 ) = item_count( index2 ) + 1
206 match = .true.
207 exit
208 endif
209 enddo
210
211 ! this integer value has not been found previously; add the value to the next position
212 ! and increment counter
213 if ( .not. match ) then
214 last = last + 1
215 value( last ) = int_vector( index1 )
216 item_count( last ) = item_count( last ) + 1
217 endif
218
219 enddo
220
221 index = maxloc( item_count, dim=1)
222 majority_value = value( index )
223
224 end function most_common_value
225
226!--------------------------------------------------------------------------------------------------
227
228 function mean( float_vector, cell_selection ) result( mean_value )
229
230 real (c_float) :: float_vector(:)
231 logical :: cell_selection(:)
232 real (c_float) :: mean_value
233
234 ! [ LOCALS ]
235 integer (c_int) :: item_count
236
237 item_count = count( cell_selection )
238
239 if ( item_count > 0 ) then
240
241 mean_value = sum( float_vector, cell_selection ) / real(item_count, c_float)
242
243 else
244
245 mean_value = -99999.0
246
247 endif
248
249 end function mean
250
251end module summary_statistics
logical(c_bool), parameter false
logical(c_bool), parameter true
character(len=1), parameter, public tab
Definition fstring.F90:171
type(date_range_t), public sim_dt
type(fstring_list_t) poly_id
subroutine add_polygon_id_to_summary_list(polygon_id)
integer(c_int) function most_common_value(int_vector, cell_selection)
subroutine write_out_values(cell_selection, poly_id)
subroutine summarize_by_landuse(cells)
subroutine initialize_summary_statistics()
subroutine summarize_by_polygon(cells)
subroutine perform_summary_statistics(cells)
logical(c_bool) anything_to_summarize
real(c_float) function mean(float_vector, cell_selection)
subroutine add_landuse_code_to_summary_list(landuse_code)
type(fstring_list_t) landuse_codes