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