Soil Water Balance (SWB2)
Loading...
Searching...
No Matches
output.F90
Go to the documentation of this file.
1module output
2
4 use exceptions, only : warn, assert, die
6 use iso_c_binding
9 use fstring, only : ascharacter
10 implicit none
11
12 real( c_double ), allocatable :: recharge_array(:)
13
15 type (t_netcdf4_file), pointer :: ncfile
17
18 type (netcdf_file_collection_t), allocatable, public :: nc_out(:)
19 type (netcdf_file_collection_t), allocatable, public :: nc_multi_sim_out(:,:)
20
21
22 integer (c_int), parameter :: ncdf_num_outputs = 32
23
25 character (len=27) :: variable_name
26 character (len=21) :: variable_units
27 real (c_float) :: valid_minimum
28 real (c_float) :: valid_maximum
29 logical (c_bool) :: is_active
30 logical (c_bool) :: multisim_outputs
31 end type output_specs_t
32
34 output_specs_t( "gross_precipitation ", "inches ", 2000.0, 0.0, true, false ), &
35 output_specs_t( "rainfall ", "inches ", 2000.0, 0.0, true, false ), &
36 output_specs_t( "snowfall ", "inches ", 2000.0, 0.0, true, false ), &
37 output_specs_t( "interception ", "inches ", 2000.0, 0.0, true, false ), &
38 output_specs_t( "interception_storage ", "inches ", 2000.0, 0.0, false, false ), &
39 output_specs_t( "runon ", "inches ", 2000.0, 0.0, true, false ), &
40 output_specs_t( "runoff ", "inches ", 2000.0, 0.0, true, false ), &
41 output_specs_t( "surface_runoff ", "inches ", 2000.0, 0.0, false, false ), &
42 output_specs_t( "snow_storage ", "inches ", 2000.0, 0.0, false, false ), &
43 output_specs_t( "surface_storage ", "inches ", 2000.0, 0.0, false, false ), &
44 output_specs_t( "soil_storage ", "inches ", 2000.0, 0.0, false, false ), &
45 output_specs_t( "delta_soil_storage ", "inches ", 2000.0, -2000.0, false, false ), &
46 output_specs_t( "reference_ET0 ", "inches ", 2000.0, 0.0, true, false ), &
47 output_specs_t( "actual_et ", "inches ", 2000.0, 0.0, true, false ), &
48 output_specs_t( "climatic_deficit ", "inches ", 2000.0, 0.0, false, false ), &
49 output_specs_t( "snowmelt ", "inches ", 2000.0, 0.0, false, false ), &
50 output_specs_t( "tmin ", "degrees_fahrenheit ", 2000.0, -2000.0, true, false ), &
51 output_specs_t( "tmax ", "degrees_fahrenheit ", 2000.0, -2000.0, true, false ), &
52 output_specs_t( "tmax_minus_tmin ", "degrees_fahrenheit ", 2000.0, -2000.0, false, false ), &
53 output_specs_t( "net_infiltration ", "inches ", 2000.0, 0.0, true, false ), &
54 output_specs_t( "rejected_net_infiltration ", "inches ", 2000.0, 0.0, true, false ), &
55 output_specs_t( "infiltration ", "inches ", 2000.0, 0.0, false, false ), &
56 output_specs_t( "irrigation ", "inches ", 2000.0, 0.0, true, false ), &
57 output_specs_t( "runoff_outside ", "inches ", 2000.0, 0.0, true, false ), &
58 output_specs_t( "crop_et ", "inches ", 2000.0, 0.0, false, false ), &
59 output_specs_t( "bare_soil_evaporation ", "inches ", 2000.0, 0.0, false, false ), &
60 output_specs_t( "growing_degree_day ", "degree_day_fahrenheit", 2000.0, 0.0, false, false ), &
61 output_specs_t( "direct_net_infiltation ", "inches ", 2000.0, 0.0, false, false ), &
62 output_specs_t( "direct_soil_moisture ", "inches ", 2000.0, 0.0, false, false ), &
63 output_specs_t( "storm_drain_capture ", "inches ", 2000.0, 0.0, false, false ), &
64 output_specs_t( "growing_season ", "0_no__1_yes ", 2000.0, 0.0, false, false ), &
65 output_specs_t( "fog ", "inches ", 2000.0, 0.0, false, false) ]
66
67 enum, bind(c)
83 end enum
84
85 logical ( c_bool ) :: output_includes_latlon = true
86
87contains
88
89 subroutine set_output_latlon_option( output_includes_latlon_l )
90
91 logical (c_bool) :: output_includes_latlon_l
92
93 output_includes_latlon = output_includes_latlon_l
94
95 end subroutine set_output_latlon_option
96
97!--------------------------------------------------------------------------------------------------
98
99 subroutine set_output_directory( output_dir_name )
100
101 character (len=*), intent(in) :: output_dir_name
102
103 output_directory_name = trim( output_dir_name )
104
105 end subroutine set_output_directory
106
107!--------------------------------------------------------------------------------------------------
108
109 subroutine set_output_prefix( output_prefix )
110
111 character (len=*), intent(in) :: output_prefix
112
113 output_prefix_name = trim( output_prefix )
114
115 end subroutine set_output_prefix
116
117!--------------------------------------------------------------------------------------------------
118
119 subroutine initialize_output(cells)
120
121 class(model_domain_t), intent(inout) :: cells
122
123 ! [ LOCALS ]
124 integer (c_int) :: iStat
125 integer (c_int) :: iIndex
126
127 allocate ( nc_out( ncdf_num_outputs ), stat=istat )
128 call assert( istat == 0, "Problem allocating memory", __file__, __line__ )
129
130 if ( .not. allocated( output_directory_name ) ) output_directory_name = ""
131 if ( .not. allocated( output_prefix_name ) ) output_prefix_name = ""
132
133 ! overrides to prevent unused variables from being written to output
134 if ( .not. associated(cells%fog) ) outspecs( ncdf_fog)%is_active = false
135
136 if ( output_includes_latlon ) then
137
138 do iindex = 1, ubound(nc_out, 1)
139
140 ! do not initialize a single output file if a series of outputs is desired
141 if ( outspecs(iindex)%multisim_outputs ) cycle
142
143 if ( outspecs(iindex)%is_active ) then
144
145 allocate ( nc_out(iindex)%ncfile )
146
148 ncfile=nc_out( iindex )%ncfile, &
149 svariablename=trim( outspecs( iindex )%variable_name ), &
150 svariableunits=trim( outspecs( iindex )%variable_units ), &
151 inx=cells%number_of_columns, &
152 iny=cells%number_of_rows, &
153 fx=cells%X, &
154 fy=cells%Y, &
155 startdate=sim_dt%start, &
156 enddate=sim_dt%end, &
157 proj4_string=cells%PROJ4_string, &
158 dplat=cells%Y_lat, &
159 dplon=cells%X_lon, &
160 fvalidmin=outspecs( iindex )%valid_minimum, &
161 fvalidmax=outspecs( iindex )%valid_maximum )
162
163 endif
164
165 enddo
166
167 else
168
169 do iindex = 1, ubound(nc_out, 1)
170
171 ! do not initialize a single output file if a series of outputs is desired
172 if ( outspecs(iindex)%multisim_outputs ) cycle
173
174 if ( outspecs(iindex)%is_active ) then
175
176 allocate ( nc_out(iindex)%ncfile )
177
179 ncfile=nc_out( iindex )%ncfile, &
180 svariablename=trim( outspecs( iindex )%variable_name ), &
181 svariableunits=trim( outspecs( iindex )%variable_units ), &
182 inx=cells%number_of_columns, &
183 iny=cells%number_of_rows, &
184 fx=cells%X, &
185 fy=cells%Y, &
186 startdate=sim_dt%start, &
187 enddate=sim_dt%end, &
188 proj4_string=cells%PROJ4_string, &
189 fvalidmin=outspecs( iindex )%valid_minimum, &
190 fvalidmax=outspecs( iindex )%valid_maximum )
191
192 endif
193
194 enddo
195
196 endif
197
198 cells%nodata_fill_value = nc_fill_float
199
200 end subroutine initialize_output
201
202 !--------------------------------------------------------------------------------------------------
203
204 subroutine initialize_multiple_sim_output(cells, number_of_simulations)
205
206 class(model_domain_t), intent(inout) :: cells
207 integer (c_int), intent(in) :: number_of_simulations
208
209 ! [ LOCALS ]
210 integer (c_int) :: iStat
211 integer (c_int) :: noutput, nsim
212
213 allocate ( nc_multi_sim_out( ncdf_num_outputs, number_of_simulations ), stat=istat )
214 call assert( istat == 0, "Problem allocating memory", __file__, __line__ )
215
216 if ( .not. allocated( output_directory_name ) ) output_directory_name = ""
217 if ( .not. allocated( output_prefix_name ) ) output_prefix_name = ""
218
219 if ( output_includes_latlon ) then
220
221 do noutput = 1, ubound(nc_multi_sim_out, 1)
222
223 ! do not initialize a series of output files unless explicitly called for
224 if ( .not. outspecs(noutput)%multisim_outputs ) cycle
225
226 if ( outspecs(noutput)%is_active ) then
227
228 do nsim=1, number_of_simulations
229
230 allocate ( nc_multi_sim_out(noutput, nsim)%ncfile )
231
233 ncfile=nc_multi_sim_out( noutput, nsim )%ncfile, &
234 svariablename=trim( outspecs( noutput )%variable_name ), &
235 svariableunits=trim( outspecs( noutput )%variable_units ), &
236 inx=cells%number_of_columns, &
237 iny=cells%number_of_rows, &
238 fx=cells%X, &
239 fy=cells%Y, &
240 startdate=sim_dt%start, &
241 enddate=sim_dt%end, &
242 proj4_string=cells%PROJ4_string, &
243 dplat=cells%Y_lat, &
244 dplon=cells%X_lon, &
245 fvalidmin=outspecs( noutput )%valid_minimum, &
246 fvalidmax=outspecs( noutput )%valid_maximum, &
247 filename_modifier="simulation_"//trim(ascharacter(nsim)) )
248
249 enddo
250
251 endif
252
253 enddo
254
255 else
256
257 do noutput = 1, ubound(nc_multi_sim_out, 1)
258
259 ! do not initialize a series of output files unless explicitly called for
260 if ( .not. outspecs(noutput)%multisim_outputs ) cycle
261
262 if ( outspecs(noutput)%is_active ) then
263
264 do nsim=1, number_of_simulations
265
266 allocate ( nc_multi_sim_out(noutput, nsim)%ncfile )
267
269 ncfile=nc_multi_sim_out( noutput, nsim )%ncfile, &
270 svariablename=trim( outspecs( noutput )%variable_name ), &
271 svariableunits=trim( outspecs( noutput )%variable_units ), &
272 inx=cells%number_of_columns, &
273 iny=cells%number_of_rows, &
274 fx=cells%X, &
275 fy=cells%Y, &
276 startdate=sim_dt%start, &
277 enddate=sim_dt%end, &
278 proj4_string=cells%PROJ4_string, &
279 fvalidmin=outspecs( noutput )%valid_minimum, &
280 fvalidmax=outspecs( noutput )%valid_maximum, &
281 filename_modifier="simulation_"//trim(ascharacter(nsim)) )
282
283 enddo
284
285 endif
286
287 enddo
288
289 endif
290
291 end subroutine initialize_multiple_sim_output
292
293!--------------------------------------------------------------------------------------------------
294
295 subroutine finalize_output(cells)
296
297 class(model_domain_t), intent(inout) :: cells
298
299 ! [ LOCALS ]
300 integer (c_int) :: iStat
301 integer (c_int) :: iIndex
302
303 do iindex = 1, ubound(nc_out, 1)
304
305 ! do not initialize a single output file if a series of outputs is desired
306 if ( outspecs(iindex)%multisim_outputs ) cycle
307
308 if ( outspecs(iindex)%is_active ) then
309
310 call netcdf_rewrite_attribute( ncfile=nc_out( iindex )%ncfile, &
311 svariablename=trim( outspecs( iindex )%variable_name ), &
312 sattributename='valid_min', &
313 rattributevalue=[outspecs(iindex)%valid_minimum])
314
315 call netcdf_rewrite_attribute( ncfile=nc_out( iindex )%ncfile, &
316 svariablename=trim( outspecs( iindex )%variable_name ), &
317 sattributename='valid_max', &
318 rattributevalue=[outspecs(iindex)%valid_maximum])
319
320 call netcdf_rewrite_attribute( ncfile=nc_out( iindex )%ncfile, &
321 svariablename=trim( outspecs( iindex )%variable_name ), &
322 sattributename='valid_range', &
323 rattributevalue=[outspecs(iindex)%valid_minimum, outspecs(iindex)%valid_maximum])
324
325 call netcdf_close_file( ncfile=nc_out( iindex )%ncfile )
326
327 endif
328
329 enddo
330
331 end subroutine finalize_output
332
333!--------------------------------------------------------------------------------------------------
334
335 subroutine output_2d_float_array( ncfile_ptr, values, cells )
336
337 type (T_NETCDF4_FILE), pointer :: ncfile_ptr
338 real (c_float), intent(in) :: values(:)
339 class(model_domain_t), intent(in) :: cells
340
341 call netcdf_put_variable_vector(ncfile=ncfile_ptr, &
342 ivarid=ncfile_ptr%iVarID(nc_time), &
343 istart=[int(sim_dt%iNumDaysFromOrigin, c_size_t)], &
344 icount=[1_c_size_t], &
345 istride=[1_c_size_t], &
346 rvalues=[real(sim_dt%iNumDaysFromOrigin, c_float)])
347
348 call netcdf_put_packed_variable_array(ncfile=ncfile_ptr, &
349 ivarid=ncfile_ptr%iVarID(nc_z), &
350 istart=[ int(sim_dt%iNumDaysFromOrigin, c_size_t), &
351 0_c_size_t, 0_c_size_t ], &
352 icount=[ 1_c_size_t, int(cells%number_of_rows, c_size_t), &
353 int(cells%number_of_columns, c_size_t) ], &
354 istride=[ 1_c_size_t, 1_c_size_t, 1_c_size_t ], &
355 lmask=cells%active, &
356 rvalues=values, &
357 rfield=cells%nodata_fill_value )
358
359 end subroutine output_2d_float_array
360
361!--------------------------------------------------------------------------------------------------
362
363 subroutine write_output(cells)
364
365 class(model_domain_t), intent(inout) :: cells
366
367 ! [ LOCALS ]
368 integer (c_int) :: iIndex
369 type (T_NETCDF4_FILE), pointer :: ncfile_ptr
370
371 do
372
373 if (.not. allocated(nc_out) ) exit
374
375 ! first put out the current time variable for all open NetCDF files
376 do iindex = 1, ubound( nc_out, 1 )
377
378 if ( outspecs(iindex)%multisim_outputs ) cycle
379
380 if ( outspecs(iindex)%is_active ) then
381
382 call netcdf_put_variable_vector(ncfile=nc_out(iindex)%ncfile, &
383 ivarid=nc_out(iindex)%ncfile%iVarID(nc_time), &
384 istart=[int(sim_dt%iNumDaysFromOrigin, c_size_t)], &
385 icount=[1_c_size_t], &
386 istride=[1_c_size_t], &
387 rvalues=[real(sim_dt%iNumDaysFromOrigin, c_float)])
388
389 endif
390
391 enddo
392
393
394 if ( outspecs( ncdf_gross_precipitation )%is_active ) then
395
396 call output_2d_float_array( ncfile_ptr=nc_out( ncdf_gross_precipitation )%ncfile, &
397 values=cells%gross_precip, &
398 cells=cells )
399 outspecs(ncdf_gross_precipitation)%valid_maximum = &
400 update_maximum_value(outspecs(ncdf_gross_precipitation)%valid_maximum, cells%gross_precip)
401 outspecs(ncdf_gross_precipitation)%valid_minimum = &
402 update_minimum_value(outspecs(ncdf_gross_precipitation)%valid_minimum, cells%gross_precip)
403
404 endif
405
406 if ( outspecs( ncdf_rainfall )%is_active ) then
407
408 call output_2d_float_array( ncfile_ptr=nc_out( ncdf_rainfall )%ncfile, &
409 values=cells%rainfall, &
410 cells=cells )
411 outspecs(ncdf_rainfall)%valid_maximum = &
412 update_maximum_value(outspecs(ncdf_rainfall)%valid_maximum, cells%rainfall)
413 outspecs(ncdf_rainfall)%valid_minimum = &
414 update_minimum_value(outspecs(ncdf_rainfall)%valid_minimum, cells%rainfall)
415
416 endif
417
418 if ( outspecs( ncdf_interception )%is_active ) then
419
420 call output_2d_float_array( ncfile_ptr=nc_out( ncdf_interception )%ncfile, &
421 values=cells%interception, &
422 cells=cells )
423 outspecs(ncdf_interception)%valid_maximum = &
424 update_maximum_value(outspecs(ncdf_interception)%valid_maximum, cells%interception)
425 outspecs(ncdf_interception)%valid_minimum = &
426 update_minimum_value(outspecs(ncdf_interception)%valid_minimum, cells%interception)
427
428 endif
429
430 if ( outspecs( ncdf_interception_storage )%is_active &
431 .and. (.not. outspecs( ncdf_interception_storage )%multisim_outputs )) then
432
433 call output_2d_float_array( ncfile_ptr=nc_out( ncdf_interception_storage )%ncfile, &
434 values=cells%interception_storage, &
435 cells=cells )
436 outspecs(ncdf_interception_storage)%valid_maximum = &
437 update_maximum_value(outspecs(ncdf_interception_storage)%valid_maximum, cells%interception_storage)
438 outspecs(ncdf_interception_storage)%valid_minimum = &
439 update_minimum_value(outspecs(ncdf_interception_storage)%valid_minimum, cells%interception_storage)
440
441 endif
442
443
444 if ( outspecs( ncdf_runoff )%is_active ) then
445
446 call output_2d_float_array( ncfile_ptr=nc_out( ncdf_runoff )%ncfile, &
447 values=cells%runoff, &
448 cells=cells )
449 outspecs(ncdf_runoff)%valid_maximum = &
450 update_maximum_value(outspecs(ncdf_runoff)%valid_maximum, cells%runoff)
451 outspecs(ncdf_runoff)%valid_minimum = &
452 update_minimum_value(outspecs(ncdf_runoff)%valid_minimum, cells%runoff)
453
454 endif
455
456
457 if ( outspecs( ncdf_surface_runoff )%is_active ) then
458
459 call output_2d_float_array( ncfile_ptr=nc_out( ncdf_surface_runoff )%ncfile, &
460 values=(cells%runoff + cells%rejected_net_infiltration), &
461 cells=cells )
462 outspecs(ncdf_surface_runoff)%valid_maximum = &
463 update_maximum_value(outspecs(ncdf_surface_runoff)%valid_maximum, (cells%runoff + cells%rejected_net_infiltration))
464 outspecs(ncdf_surface_runoff)%valid_minimum = &
465 update_minimum_value(outspecs(ncdf_surface_runoff)%valid_minimum, (cells%runoff + cells%rejected_net_infiltration))
466
467 endif
468
469
470 if ( outspecs( ncdf_runoff_outside )%is_active ) then
471
472 call output_2d_float_array( ncfile_ptr=nc_out( ncdf_runoff_outside )%ncfile, &
473 values=cells%runoff_outside, &
474 cells=cells )
475 outspecs(ncdf_runoff_outside)%valid_maximum = &
476 update_maximum_value(outspecs(ncdf_runoff_outside)%valid_maximum, cells%runoff_outside)
477 outspecs(ncdf_runoff_outside)%valid_minimum = &
478 update_minimum_value(outspecs(ncdf_runoff_outside)%valid_minimum, cells%runoff_outside)
479
480 endif
481
482
483 if ( outspecs( ncdf_runon )%is_active ) then
484
485 call output_2d_float_array( ncfile_ptr=nc_out( ncdf_runon )%ncfile, &
486 values=cells%runon, &
487 cells=cells )
488 outspecs(ncdf_runon)%valid_maximum = &
489 update_maximum_value(outspecs(ncdf_runon)%valid_maximum, cells%runon)
490 outspecs(ncdf_runon)%valid_minimum = &
491 update_minimum_value(outspecs(ncdf_runon)%valid_minimum, cells%runon)
492
493 endif
494
495
496 if ( outspecs( ncdf_infiltration )%is_active ) then
497
498 call output_2d_float_array( ncfile_ptr=nc_out( ncdf_infiltration )%ncfile, &
499 values=cells%infiltration, &
500 cells=cells )
501 outspecs(ncdf_infiltration)%valid_maximum = &
502 update_maximum_value(outspecs(ncdf_infiltration)%valid_maximum, cells%infiltration)
503 outspecs(ncdf_infiltration)%valid_minimum = &
504 update_minimum_value(outspecs(ncdf_infiltration)%valid_minimum, cells%infiltration)
505
506 endif
507
508 if ( outspecs( ncdf_snowfall )%is_active ) then
509
510 call output_2d_float_array( ncfile_ptr=nc_out( ncdf_snowfall )%ncfile, &
511 values=cells%snowfall, &
512 cells=cells )
513 outspecs(ncdf_snowfall)%valid_maximum = &
514 update_maximum_value(outspecs(ncdf_snowfall)%valid_maximum, cells%snowfall)
515 outspecs(ncdf_snowfall)%valid_minimum = &
516 update_minimum_value(outspecs(ncdf_snowfall)%valid_minimum, cells%snowfall)
517
518 endif
519
520 if ( outspecs( ncdf_snowmelt )%is_active ) then
521
522 call output_2d_float_array( ncfile_ptr=nc_out( ncdf_snowmelt )%ncfile, &
523 values=cells%snowmelt, &
524 cells=cells )
525 outspecs(ncdf_snowmelt)%valid_maximum = &
526 update_maximum_value(outspecs(ncdf_snowmelt)%valid_maximum, cells%snowmelt)
527 outspecs(ncdf_snowmelt)%valid_minimum = &
528 update_minimum_value(outspecs(ncdf_snowmelt)%valid_minimum, cells%snowmelt)
529
530 endif
531
532 if ( outspecs( ncdf_snow_storage )%is_active ) then
533
534 call output_2d_float_array( ncfile_ptr=nc_out( ncdf_snow_storage )%ncfile, &
535 values=cells%snow_storage, &
536 cells=cells )
537 outspecs(ncdf_snow_storage)%valid_maximum = &
538 update_maximum_value(outspecs(ncdf_snow_storage)%valid_maximum, cells%snow_storage)
539 outspecs(ncdf_snow_storage)%valid_minimum = &
540 update_minimum_value(outspecs(ncdf_snow_storage)%valid_minimum, cells%snow_storage)
541
542 endif
543
544 if ( outspecs( ncdf_surface_storage )%is_active &
545 .and. (.not. outspecs( ncdf_surface_storage )%multisim_outputs) ) then
546
547 call output_2d_float_array( ncfile_ptr=nc_out( ncdf_surface_storage )%ncfile, &
548 values=real(cells%surface_storage, c_float), &
549 cells=cells )
550 outspecs(ncdf_surface_storage)%valid_maximum = &
551 update_maximum_value(outspecs(ncdf_surface_storage)%valid_maximum, real(cells%surface_storage, c_float))
552 outspecs(ncdf_surface_storage)%valid_minimum = &
553 update_minimum_value(outspecs(ncdf_surface_storage)%valid_minimum, real(cells%surface_storage, c_float))
554
555 endif
556
557 if ( outspecs( ncdf_soil_storage )%is_active &
558 .and. (.not. outspecs( ncdf_soil_storage )%multisim_outputs) ) then
559
560 call output_2d_float_array( ncfile_ptr=nc_out( ncdf_soil_storage )%ncfile, &
561 values=real(cells%soil_storage, c_float), &
562 cells=cells )
563 outspecs(ncdf_soil_storage)%valid_maximum = &
564 update_maximum_value(outspecs(ncdf_soil_storage)%valid_maximum, real(cells%soil_storage, c_float))
565 outspecs(ncdf_soil_storage)%valid_minimum = &
566 update_minimum_value(outspecs(ncdf_soil_storage)%valid_minimum, real(cells%soil_storage, c_float))
567
568 endif
569
570 if ( outspecs( ncdf_delta_soil_storage )%is_active ) then
571
572 call output_2d_float_array( ncfile_ptr=nc_out( ncdf_delta_soil_storage )%ncfile, &
573 values=cells%delta_soil_storage, &
574 cells=cells )
575 outspecs(ncdf_delta_soil_storage)%valid_maximum = &
576 update_maximum_value(outspecs(ncdf_delta_soil_storage)%valid_maximum, cells%delta_soil_storage)
577 outspecs(ncdf_delta_soil_storage)%valid_minimum = &
578 update_minimum_value(outspecs(ncdf_delta_soil_storage)%valid_minimum, cells%delta_soil_storage)
579
580 endif
581
582 if ( outspecs( ncdf_net_infiltration )%is_active &
583 .and. (.not. outspecs( ncdf_net_infiltration )%multisim_outputs) ) then
584
585 call output_2d_float_array( ncfile_ptr=nc_out( ncdf_net_infiltration )%ncfile, &
586 values=cells%net_infiltration, &
587 cells=cells )
588 outspecs(ncdf_net_infiltration)%valid_maximum = &
589 update_maximum_value(outspecs(ncdf_net_infiltration)%valid_maximum, cells%net_infiltration)
590 outspecs(ncdf_net_infiltration)%valid_minimum = &
591 update_minimum_value(outspecs(ncdf_net_infiltration)%valid_minimum, cells%net_infiltration)
592
593 endif
594
595 if ( outspecs( ncdf_reference_et0 )%is_active ) then
596
597 call output_2d_float_array( ncfile_ptr=nc_out( ncdf_reference_et0 )%ncfile, &
598 values=real(cells%reference_ET0, c_float), &
599 cells=cells )
600 outspecs(ncdf_reference_et0)%valid_maximum = &
601 update_maximum_value(outspecs(ncdf_reference_et0)%valid_maximum, real(cells%reference_et0, c_float))
602 outspecs(ncdf_reference_et0)%valid_minimum = &
603 update_minimum_value(outspecs(ncdf_reference_et0)%valid_minimum, real(cells%reference_et0, c_float))
604
605 endif
606
607 if ( outspecs( ncdf_actual_et )%is_active &
608 .and. (.not. outspecs( ncdf_actual_et )%multisim_outputs) ) then
609
610 call output_2d_float_array( ncfile_ptr=nc_out( ncdf_actual_et )%ncfile, &
611 values=real(cells%actual_et, c_float), &
612 cells=cells )
613 outspecs(ncdf_actual_et)%valid_maximum = &
614 update_maximum_value(outspecs(ncdf_actual_et)%valid_maximum, real(cells%actual_et, c_float))
615 outspecs(ncdf_actual_et)%valid_minimum = &
616 update_minimum_value(outspecs(ncdf_actual_et)%valid_minimum, real(cells%actual_et, c_float))
617
618 endif
619
620 if ( outspecs( ncdf_climatic_deficit )%is_active &
621 .and. (.not. outspecs( ncdf_climatic_deficit )%multisim_outputs) ) then
622
623 call output_2d_float_array( ncfile_ptr=nc_out( ncdf_climatic_deficit )%ncfile, &
624 values=real(cells%climatic_deficit, c_float), &
625 cells=cells )
626 outspecs(ncdf_climatic_deficit)%valid_maximum = &
627 update_maximum_value(outspecs(ncdf_climatic_deficit)%valid_maximum, real(cells%climatic_deficit, c_float))
628 outspecs(ncdf_climatic_deficit)%valid_minimum = &
629 update_minimum_value(outspecs(ncdf_climatic_deficit)%valid_minimum, real(cells%climatic_deficit, c_float))
630
631 endif
632
633 if ( outspecs( ncdf_tmin )%is_active ) then
634
635 call output_2d_float_array( ncfile_ptr=nc_out( ncdf_tmin )%ncfile, &
636 values=cells%tmin, &
637 cells=cells )
638 outspecs(ncdf_tmin)%valid_maximum = &
639 update_maximum_value(outspecs(ncdf_tmin)%valid_maximum, cells%tmin)
640 outspecs(ncdf_tmin)%valid_minimum = &
641 update_minimum_value(outspecs(ncdf_tmin)%valid_minimum, cells%tmin)
642
643 endif
644
645 if ( outspecs( ncdf_tmax )%is_active ) then
646
647 call output_2d_float_array( ncfile_ptr=nc_out( ncdf_tmax )%ncfile, &
648 values=cells%tmax, &
649 cells=cells )
650 outspecs(ncdf_tmax)%valid_maximum = &
651 update_maximum_value(outspecs(ncdf_tmax)%valid_maximum, cells%tmax)
652 outspecs(ncdf_tmax)%valid_minimum = &
653 update_minimum_value(outspecs(ncdf_tmax)%valid_minimum, cells%tmax)
654
655 endif
656
657 if ( outspecs( ncdf_tmax_minus_tmin )%is_active ) then
658
659 call output_2d_float_array( ncfile_ptr=nc_out( ncdf_tmax_minus_tmin )%ncfile, &
660 values=cells%tmax_minus_tmin, &
661 cells=cells )
662 outspecs(ncdf_tmax)%valid_maximum = &
663 update_maximum_value(outspecs(ncdf_tmax)%valid_maximum, cells%tmax_minus_tmin)
664 outspecs(ncdf_tmax)%valid_minimum = &
665 update_minimum_value(outspecs(ncdf_tmax)%valid_minimum, cells%tmax_minus_tmin)
666
667 endif
668
669 if ( outspecs( ncdf_irrigation )%is_active ) then
670
671 call output_2d_float_array( ncfile_ptr=nc_out( ncdf_irrigation )%ncfile, &
672 values=cells%irrigation, &
673 cells=cells )
674 outspecs(ncdf_irrigation)%valid_maximum = &
675 update_maximum_value(outspecs(ncdf_irrigation)%valid_maximum, cells%irrigation)
676 outspecs(ncdf_irrigation)%valid_minimum = &
677 update_minimum_value(outspecs(ncdf_irrigation)%valid_minimum, cells%irrigation)
678
679 endif
680
681
682 if ( outspecs( ncdf_gdd )%is_active ) then
683
684 call output_2d_float_array( ncfile_ptr=nc_out( ncdf_gdd )%ncfile, &
685 values=cells%gdd, &
686 cells=cells )
687 outspecs(ncdf_gdd)%valid_maximum = &
688 update_maximum_value(outspecs(ncdf_gdd)%valid_maximum, cells%gdd)
689 outspecs(ncdf_gdd)%valid_minimum = &
690 update_minimum_value(outspecs(ncdf_gdd)%valid_minimum, cells%gdd)
691
692 endif
693
694 if ( outspecs( ncdf_rejected_net_infiltration )%is_active ) then
695
697 values=cells%rejected_net_infiltration, &
698 cells=cells )
700 update_maximum_value(outspecs(ncdf_rejected_net_infiltration)%valid_maximum, cells%rejected_net_infiltration)
702 update_minimum_value(outspecs(ncdf_rejected_net_infiltration)%valid_minimum, cells%rejected_net_infiltration)
703
704 endif
705
706 if ( outspecs( ncdf_crop_et )%is_active ) then
707
708 call output_2d_float_array( ncfile_ptr=nc_out( ncdf_crop_et )%ncfile, &
709 values=cells%crop_etc, &
710 cells=cells )
711 outspecs(ncdf_crop_et)%valid_maximum = &
712 update_maximum_value(outspecs(ncdf_crop_et)%valid_maximum, cells%crop_etc)
713 outspecs(ncdf_crop_et)%valid_minimum = &
714 update_minimum_value(outspecs(ncdf_crop_et)%valid_minimum, cells%crop_etc)
715
716 endif
717
718 if ( outspecs( ncdf_bare_soil_evap )%is_active ) then
719
720 call output_2d_float_array( ncfile_ptr=nc_out( ncdf_bare_soil_evap )%ncfile, &
721 values=cells%bare_soil_evap, &
722 cells=cells )
723 outspecs(ncdf_bare_soil_evap)%valid_maximum = &
724 update_maximum_value(outspecs(ncdf_bare_soil_evap)%valid_maximum, cells%bare_soil_evap)
725 outspecs(ncdf_bare_soil_evap)%valid_minimum = &
726 update_minimum_value(outspecs(ncdf_bare_soil_evap)%valid_minimum, cells%bare_soil_evap)
727
728 endif
729
730 if ( outspecs( ncdf_direct_net_infiltration )%is_active ) then
731
732 call output_2d_float_array( ncfile_ptr=nc_out( ncdf_direct_net_infiltration )%ncfile, &
733 values=cells%direct_net_infiltration, &
734 cells=cells )
735 outspecs(ncdf_direct_net_infiltration)%valid_maximum = &
736 update_maximum_value(outspecs(ncdf_direct_net_infiltration)%valid_maximum, cells%direct_net_infiltration)
737 outspecs(ncdf_direct_net_infiltration)%valid_minimum = &
738 update_minimum_value(outspecs(ncdf_direct_net_infiltration)%valid_minimum, cells%direct_net_infiltration)
739
740 endif
741
742 if ( outspecs( ncdf_direct_soil_moisture )%is_active ) then
743
744 call output_2d_float_array( ncfile_ptr=nc_out( ncdf_direct_soil_moisture )%ncfile, &
745 values=cells%direct_soil_moisture, &
746 cells=cells )
747 outspecs(ncdf_direct_soil_moisture)%valid_maximum = &
748 update_maximum_value(outspecs(ncdf_direct_soil_moisture)%valid_maximum, cells%direct_soil_moisture)
749 outspecs(ncdf_direct_soil_moisture)%valid_minimum = &
750 update_minimum_value(outspecs(ncdf_direct_soil_moisture)%valid_minimum, cells%direct_soil_moisture)
751
752 endif
753
754 if ( outspecs( ncdf_storm_drain_capture )%is_active ) then
755
756 call output_2d_float_array( ncfile_ptr=nc_out( ncdf_storm_drain_capture )%ncfile, &
757 values=cells%storm_drain_capture, &
758 cells=cells )
759 outspecs(ncdf_storm_drain_capture)%valid_maximum = &
760 update_maximum_value(outspecs(ncdf_storm_drain_capture)%valid_maximum, cells%storm_drain_capture)
761 outspecs(ncdf_storm_drain_capture)%valid_minimum = &
762 update_minimum_value(outspecs(ncdf_storm_drain_capture)%valid_minimum, cells%storm_drain_capture)
763
764 endif
765
766 if ( outspecs( ncdf_growing_season )%is_active ) then
767
768 call output_2d_float_array( ncfile_ptr=nc_out( ncdf_growing_season )%ncfile, &
769 values=asfloat(cells%it_is_growing_season), &
770 cells=cells )
771 outspecs(ncdf_growing_season)%valid_maximum = &
772 update_maximum_value(outspecs(ncdf_growing_season)%valid_maximum, asfloat(cells%it_is_growing_season))
773 outspecs(ncdf_growing_season)%valid_minimum = &
774 update_minimum_value(outspecs(ncdf_growing_season)%valid_minimum, asfloat(cells%it_is_growing_season))
775
776 endif
777
778
779 if ( outspecs( ncdf_fog )%is_active ) then
780
781 call output_2d_float_array( ncfile_ptr=nc_out( ncdf_fog )%ncfile, &
782 values=cells%fog, &
783 cells=cells )
784 outspecs(ncdf_fog)%valid_maximum = &
785 update_maximum_value(outspecs(ncdf_fog)%valid_maximum, cells%fog)
786 outspecs(ncdf_fog)%valid_minimum = &
787 update_minimum_value(outspecs(ncdf_fog)%valid_minimum, cells%fog)
788
789 endif
790
791 exit
792
793 enddo
794
795 end subroutine write_output
796
797!-------------------------------------------------------------------------------
798
799 subroutine write_multi_sim_output(cells, simulation_number)
800
801 class(model_domain_t), intent(inout) :: cells
802 integer (c_int), intent(in) :: simulation_number
803
804 ! [ LOCALS ]
805 integer (c_int) :: iIndex
806 type (T_NETCDF4_FILE), pointer :: ncfile_ptr
807
808
809
810 ! first put out the current time variable for all open NetCDF files
811 do iindex = 1, ubound( nc_multi_sim_out, 1 )
812
813 ! do not write output unless multisim flag has been set
814 if ( .not. outspecs(iindex)%multisim_outputs ) cycle
815
816 if ( outspecs(iindex)%is_active ) then
817
818
819 call netcdf_put_variable_vector(ncfile= &
820 nc_multi_sim_out(iindex,simulation_number)%ncfile, &
821 ivarid=nc_multi_sim_out(iindex, simulation_number)%ncfile%iVarID(nc_time), &
822 istart=[int(sim_dt%iNumDaysFromOrigin, c_size_t)], &
823 icount=[1_c_size_t], &
824 istride=[1_c_size_t], &
825 rvalues=[real(sim_dt%iNumDaysFromOrigin, c_float)])
826
827 endif
828
829 enddo
830
831 if ( outspecs( ncdf_snow_storage )%is_active &
832 .and. outspecs(ncdf_snow_storage)%multisim_outputs ) &
833
835 ncfile_ptr=nc_multi_sim_out( ncdf_snow_storage, simulation_number )%ncfile, &
836 values=cells%snow_storage, &
837 cells=cells )
838
839 if ( outspecs( ncdf_soil_storage )%is_active &
840 .and. outspecs(ncdf_soil_storage)%multisim_outputs ) &
841
843 ncfile_ptr=nc_multi_sim_out( ncdf_soil_storage, simulation_number )%ncfile, &
844 values=real(cells%soil_storage, c_float), &
845 cells=cells )
846
847 if ( outspecs( ncdf_net_infiltration )%is_active &
848 .and. outspecs(ncdf_net_infiltration)%multisim_outputs ) &
849
851 ncfile_ptr=nc_multi_sim_out( ncdf_net_infiltration, simulation_number )%ncfile, &
852 values=cells%net_infiltration, &
853 cells=cells )
854
855 if ( outspecs( ncdf_actual_et )%is_active &
856 .and. outspecs(ncdf_actual_et)%multisim_outputs ) &
857
859 ncfile_ptr=nc_multi_sim_out( ncdf_actual_et, simulation_number )%ncfile, &
860 values=real(cells%actual_et, c_float), &
861 cells=cells )
862
863 if ( outspecs( ncdf_interception_storage )%is_active &
864 .and. outspecs(ncdf_interception_storage)%multisim_outputs ) &
865
867 ncfile_ptr=nc_multi_sim_out( ncdf_interception_storage, simulation_number )%ncfile, &
868 values=real(cells%interception_storage, c_float), &
869 cells=cells )
870
871 if ( outspecs( ncdf_surface_storage )%is_active &
872 .and. outspecs(ncdf_surface_storage)%multisim_outputs ) &
873
875 ncfile_ptr=nc_multi_sim_out( ncdf_surface_storage, simulation_number )%ncfile, &
876 values=real(cells%surface_storage, c_float), &
877 cells=cells )
878
879 end subroutine write_multi_sim_output
880
881 pure function update_minimum_value(current_minimum, values) result(new_minimum)
882
883 real (c_float), intent(in) :: current_minimum
884 real (c_float), intent(in) :: values(:)
885
886 real (c_float) :: new_minimum
887
888 new_minimum = min(current_minimum, minval(values))
889
890 end function update_minimum_value
891
892!------------------------------------------------------------------------------
893
894 pure function update_maximum_value(current_maximum, values) result(new_maximum)
895
896 real (c_float), intent(in) :: current_maximum
897 real (c_float), intent(in) :: values(:)
898
899 real (c_float) :: new_maximum
900
901 new_maximum = max(current_maximum, maxval(values))
902
903 end function update_maximum_value
904
905end module output
This module contains physical constants and convenience functions aimed at performing unit conversion...
logical(c_bool), parameter, public true
character(len=:), allocatable, public output_prefix_name
logical(c_bool), parameter, public false
character(len=:), allocatable, public output_directory_name
subroutine, public warn(smessage, smodule, iline, shints, lfatal, iloglevel, lecho)
subroutine, public die(smessage, smodule, iline, shints, scalledby, icalledbyline)
Provide support for use of netCDF files as input for time-varying, gridded meteorlogic data,...
subroutine, public netcdf_open_and_prepare_as_output(ncfile, svariablename, svariableunits, inx, iny, fx, fy, startdate, enddate, proj4_string, history_list, executable_name, dplat, dplon, fvalidmin, fvalidmax, write_time_bounds, filename_prefix, filename_modifier)
subroutine, public netcdf_put_packed_variable_array(ncfile, ivarid, istart, icount, istride, lmask, ivalues, ifield, i2values, i2field, rvalues, rfield, dpvalues, dpfield)
subroutine, public netcdf_close_file(ncfile)
integer(c_int), parameter, public nc_time
@TODO: implement a more flexible way of tracking variable IDs; presently the code can break if lat an...
real(c_float), parameter, public nc_fill_float
subroutine, public netcdf_put_variable_vector(ncfile, ivarid, istart, icount, istride, ivalues, i2values, rvalues, dpvalues)
integer(c_int), parameter, public nc_z
subroutine, public netcdf_rewrite_attribute(ncfile, svariablename, sattributename, sattributevalue, iattributevalue, rattributevalue, dpattributevalue)
subroutine write_output(cells)
Definition output.F90:364
integer(c_int), parameter ncdf_num_outputs
Definition output.F90:22
real(c_double), dimension(:), allocatable recharge_array
Definition output.F90:12
logical(c_bool) output_includes_latlon
Definition output.F90:85
subroutine write_multi_sim_output(cells, simulation_number)
Definition output.F90:800
type(output_specs_t), dimension(ncdf_num_outputs) outspecs
Definition output.F90:33
@ ncdf_delta_soil_storage
Definition output.F90:68
@ ncdf_infiltration
Definition output.F90:68
@ ncdf_irrigation
Definition output.F90:68
@ ncdf_tmax_minus_tmin
Definition output.F90:68
@ ncdf_runon
Definition output.F90:68
@ ncdf_interception
Definition output.F90:68
@ ncdf_climatic_deficit
Definition output.F90:68
@ ncdf_snowfall
Definition output.F90:68
@ ncdf_rejected_net_infiltration
Definition output.F90:68
@ ncdf_surface_runoff
Definition output.F90:68
@ ncdf_direct_net_infiltration
Definition output.F90:68
@ ncdf_bare_soil_evap
Definition output.F90:68
@ ncdf_tmax
Definition output.F90:68
@ ncdf_snow_storage
Definition output.F90:68
@ ncdf_interception_storage
Definition output.F90:68
@ ncdf_storm_drain_capture
Definition output.F90:68
@ ncdf_gross_precipitation
Definition output.F90:68
@ ncdf_actual_et
Definition output.F90:68
@ ncdf_gdd
Definition output.F90:68
@ ncdf_net_infiltration
Definition output.F90:68
@ ncdf_runoff
Definition output.F90:68
@ ncdf_growing_season
Definition output.F90:68
@ ncdf_direct_soil_moisture
Definition output.F90:68
@ ncdf_reference_et0
Definition output.F90:68
@ ncdf_fog
Definition output.F90:68
@ ncdf_tmin
Definition output.F90:68
@ ncdf_snowmelt
Definition output.F90:68
@ ncdf_soil_storage
Definition output.F90:68
@ ncdf_crop_et
Definition output.F90:68
@ ncdf_rainfall
Definition output.F90:68
@ ncdf_surface_storage
Definition output.F90:68
@ ncdf_runoff_outside
Definition output.F90:68
type(netcdf_file_collection_t), dimension(:,:), allocatable, public nc_multi_sim_out
Definition output.F90:19
subroutine initialize_output(cells)
Definition output.F90:120
subroutine finalize_output(cells)
Definition output.F90:296
subroutine set_output_prefix(output_prefix)
Definition output.F90:110
type(netcdf_file_collection_t), dimension(:), allocatable, public nc_out
Definition output.F90:18
subroutine initialize_multiple_sim_output(cells, number_of_simulations)
Definition output.F90:205
pure real(c_float) function update_maximum_value(current_maximum, values)
Definition output.F90:895
subroutine set_output_directory(output_dir_name)
Definition output.F90:100
subroutine output_2d_float_array(ncfile_ptr, values, cells)
Definition output.F90:336
subroutine set_output_latlon_option(output_includes_latlon_l)
Definition output.F90:90
pure real(c_float) function update_minimum_value(current_minimum, values)
Definition output.F90:882
type(date_range_t), public sim_dt