Soil Water Balance (SWB2)
Loading...
Searching...
No Matches
model_domain.F90
Go to the documentation of this file.
2
3 use iso_c_binding
8 use datetime
9 use exceptions
10 use logfiles
14 use grid
15 use parameters, only : params, params_dict
17 use fstring
18 implicit none
19
20 public
21
22 ! concept: the only state variables that should appear in this module should be
23 ! those that are required regardless of what other program options are active
24 !
25 !
26 ! additionally: concept is to have a set of more or less standard procedure pointers that are common to
27 ! a soil moisture balance; the pointer may be set to a different procedure thus changing
28 ! the behavior and mechanisms within the model
29
31
32 character (len=:), allocatable :: output_directory_name
33 character (len=:), allocatable :: proj4_string
34 integer (c_int) :: number_of_columns
35 integer (c_int) :: number_of_rows
36 real (c_double) :: x_ll, y_ll
37 real (c_double) :: x_ur, y_ur
38 real (c_double), allocatable :: x(:), y(:)
39 real (c_double), allocatable :: x_lon(:,:), y_lat(:,:)
40 real (c_double) :: gridcellsize
41
42 logical (c_bool), allocatable :: active(:,:)
43 real (c_float), allocatable :: nodata_fill_value(:,:)
44 real (c_float), allocatable :: array_output(:,:)
45
46 integer (c_int), allocatable :: landuse_code(:)
47 integer (c_int), allocatable :: landuse_index(:)
48 integer (c_int), allocatable :: soil_code(:)
49 integer (c_int), allocatable :: soil_group(:)
50 integer (c_int), allocatable :: num_upslope_connections(:)
51 integer (c_int), allocatable :: sum_upslope_cells(:)
52
53 integer (c_int), allocatable :: col_num_2d(:,:)
54 integer (c_int), allocatable :: row_num_2d(:,:)
55
56 integer (c_int), allocatable :: col_num_1d(:)
57 integer (c_int), allocatable :: row_num_1d(:)
58
59 real (c_float), allocatable :: pervious_fraction(:)
60 real (c_float), allocatable :: canopy_cover_fraction(:)
61 real (c_float), allocatable :: awc(:)
62 real (c_float), allocatable :: curve_num_adj(:)
63 real (c_float), allocatable :: gdd(:)
64 real (c_float), allocatable :: crop_coefficient_kcb(:)
65 real (c_double), allocatable :: surf_evap_coef_ke(:)
66 real (c_double), allocatable :: plant_stress_coef_ks(:)
67 real (c_double), allocatable :: evap_reduction_coef_kr(:)
68 real (c_double), allocatable :: total_available_water_taw(:)
69 real (c_double), allocatable :: readily_available_water_raw(:)
70
71 real (c_float), allocatable :: continuous_frozen_ground_index(:)
72 real (c_float), allocatable :: cfgi_lower_limit(:)
73 real (c_float), allocatable :: cfgi_upper_limit(:)
74
75 real (c_float), allocatable :: hargreaves_et0_slope(:)
76 real (c_float), allocatable :: hargreaves_et0_exponent(:)
77 real (c_float), allocatable :: hargreaves_et0_constant(:)
78
79 real (c_float), allocatable :: rooting_depth_max(:)
80
81 integer (c_int), allocatable :: polygon_id(:)
82 real (c_float), allocatable :: latitude(:)
83 real (c_double), allocatable :: reference_et0(:)
84 real (c_float), allocatable :: crop_etc(:)
85
86 real (c_double), allocatable :: actual_et_interception(:)
87 real (c_double), allocatable :: actual_et_impervious(:)
88 real (c_double), allocatable :: actual_et_soil(:)
89 real (c_double), pointer :: actual_et(:)
90 real (c_float), allocatable :: bare_soil_evap(:)
91
92 real (c_float), allocatable :: inflow(:)
93 real (c_float), allocatable :: runon(:)
94 real (c_float), allocatable :: runoff(:)
95 real (c_float), allocatable :: monthly_runoff(:)
96 real (c_float), allocatable :: runoff_outside(:)
97 real (c_float), allocatable :: outflow(:)
98 real (c_float), allocatable :: infiltration(:)
99 real (c_float), allocatable :: potential_snowmelt(:)
100 real (c_float), allocatable :: snowmelt(:)
101 type (general_grid_t), pointer :: pgrdout
102 real (c_float), allocatable :: interception(:)
103 real (c_float), pointer :: interception_storage(:)
104 real (c_float), allocatable :: interception_storage_max(:)
105
106 real (c_float), pointer :: snow_storage(:)
107 real (c_double), pointer :: surface_storage(:)
108 real (c_float), allocatable :: surface_storage_max(:)
109 real (c_float), allocatable :: surface_storage_excess(:)
110 real (c_float), allocatable :: storm_drain_capture(:)
111 real (c_float), allocatable :: delta_soil_storage(:)
112 real (c_double), pointer :: soil_storage(:)
113 real (c_float), allocatable :: soil_storage_max(:)
114 real (c_double), allocatable :: soil_moisture_deficit(:)
115 real (c_float), pointer :: net_infiltration(:)
116 real (c_float), allocatable :: rejected_net_infiltration(:)
117 real (c_float), allocatable :: direct_net_infiltration(:)
118 real (c_float), allocatable :: direct_soil_moisture(:)
119 real (c_float), allocatable :: current_rooting_depth(:)
120 real (c_float), allocatable :: current_plant_height(:)
121 integer (c_int), allocatable :: number_of_days_since_planting(:)
122 logical (c_bool), allocatable :: it_is_growing_season(:)
123
124 real (c_float), allocatable :: gross_precip(:)
125 real (c_float), allocatable :: monthly_gross_precip(:)
126 real (c_float), pointer :: fog(:)
127 real (c_float), allocatable :: rainfall(:)
128 real (c_float), allocatable :: net_rainfall(:)
129 real (c_float), allocatable :: snowfall(:)
130 real (c_float), allocatable :: net_snowfall(:)
131 real (c_float), allocatable :: irrigation(:)
132
133 real (c_float), allocatable :: tmin(:)
134 real (c_float), allocatable :: tmax(:)
135 real (c_float), allocatable :: tmean(:)
136 real (c_float), allocatable :: tmax_minus_tmin(:)
137 real (c_float), allocatable :: climatic_deficit(:)
138
139 real (c_float), allocatable :: routing_fraction(:)
140
141 integer (c_int), allocatable :: sort_order(:)
142
143 real (c_double), allocatable :: adjusted_depletion_fraction_p(:)
144 real (c_float), allocatable :: fraction_exposed_and_wetted_soil(:)
145
146 real (c_float), allocatable :: evaporable_water_storage(:)
147 real (c_float), allocatable :: evaporable_water_deficit(:)
148
149 ! member variables that are only allocated if particular optional methods are invoked
150
151 real (c_float), allocatable :: irrigation_mask(:)
152
153 !> declare procedure pointers - these will have to be initialized elsewhere
154 procedure( array_method ), pointer :: init_interception
155 procedure( array_method ), pointer :: init_runoff
156 procedure( array_method ), pointer :: init_reference_et
157 procedure( array_method ), pointer :: init_actual_et
158 procedure( array_method ), pointer :: init_routing
159 procedure( array_method ), pointer :: init_soil_storage_max
160 procedure( array_method ), pointer :: init_snowfall
161 procedure( array_method ), pointer :: init_snowmelt
162 procedure( array_method ), pointer :: init_precipitation_data
163 procedure( array_method ), pointer :: init_fog
164 procedure( array_method ), pointer :: init_irrigation
165 procedure( array_method ), pointer :: init_direct_net_infiltration
166 procedure( array_method ), pointer :: init_direct_soil_moisture
167 procedure( array_method ), pointer :: update_landuse_codes
168 procedure( array_method ), pointer :: update_irrigation_mask
169 procedure( array_method ), pointer :: init_gdd
170 procedure( array_method ), pointer :: init_growing_season
171 procedure( array_method ), pointer :: init_awc
172 procedure( array_method ), pointer :: init_crop_coefficient
173 procedure( array_method ), pointer :: calc_interception
174 procedure( index_method ), pointer :: calc_climatic_water_deficit
175 procedure( array_method ), pointer :: update_crop_coefficient
176 procedure( array_method ), pointer :: init_rooting_depth
177 procedure( array_method ), pointer :: update_rooting_depth
178 procedure( array_method ), pointer :: init_continuous_frozen_ground_index
179 procedure( array_method ), pointer :: calc_continuous_frozen_ground_index
180 procedure( array_method ), pointer :: init_maximum_net_infiltration
181 procedure( index_method ), pointer :: calc_maximum_net_infiltration
182 procedure( index_method ), pointer :: calc_runoff
183 procedure( array_method ), pointer :: calc_reference_et
184 procedure( index_method ), pointer :: calc_routing
185 procedure( index_method ), pointer :: calc_actual_et
186 procedure( array_method ), pointer :: calc_snowfall
187 procedure( array_method ), pointer :: calc_snowmelt
188 procedure( array_method ), pointer :: calc_fog
189 procedure( index_method ), pointer :: calc_irrigation
190 procedure( array_method ), pointer :: calc_gdd
191 procedure( array_method ), pointer :: update_growing_season
192 procedure( index_method ), pointer :: calc_direct_net_infiltration
193 procedure( index_method ), pointer :: calc_direct_soil_moisture
194 procedure(array_method), pointer :: output_irrigation
195 procedure(array_method), pointer :: dump_variables
196 procedure( array_method ), pointer :: read_awc_data
197 procedure( array_method ), pointer :: get_precipitation_data
198 procedure( array_method ), pointer :: get_minimum_air_temperature_data
199 procedure( array_method ), pointer :: get_maximum_air_temperature_data
200 procedure( array_method ), pointer :: calculate_mean_air_temperature
201 procedure( array_method ), pointer :: calculate_range_in_air_temperature
202
203 contains
204
206 procedure :: update_rooting_depth_table => model_update_rooting_depth_table_sub
207
209 generic :: initialize_arrays => initialize_arrays_sub
210
212 generic :: initialize_grid => initialize_grid_sub
213
215 generic :: set_default_method_pointers => set_default_procedure_pointers_sub
216
218 generic :: set_method_pointers => set_method_pointers_sub
219
221 generic :: set_inactive_cells => set_inactive_cells_sub
222
224
225 procedure :: get_weather_data
226
227 procedure :: set_output_directory => set_output_directory_sub
228
230 generic :: initialize_methods => initialize_methods_sub
231
233 generic :: summarize => summarize_state_variables_sub
234
236 generic :: initialize_row_column_indices => initialize_row_column_indices_sub
237
239 generic :: row_column_to_index => row_column_to_index_fn
240
242 generic :: initialize_growing_season => model_initialize_growing_season
243
244 end type model_domain_t
245
246 ! array method: designed to be called using whole-array notation
247 ! public array_method
248 abstract interface
249 subroutine array_method( this )
250 import :: model_domain_t
251 class( model_domain_t ), intent(inout) :: this
252 end subroutine array_method
253 end interface
254
255 ! indexed method: designed to be called sequentially with explicit
256 ! index values provided
257 ! public index_method
258 abstract interface
259 subroutine index_method( this, index )
260 import :: model_domain_t, c_int
261 class( model_domain_t ), intent(inout) :: this
262 integer (c_int), intent(in) :: index
263 end subroutine index_method
264 end interface
265
266 interface minmaxmean
267 procedure :: minmaxmean_float
268 procedure :: minmaxmean_int
269 end interface minmaxmean
270
272 integer (c_int) :: unitnum = 0
273 integer (c_int) :: col = 0
274 integer (c_int) :: row = 0
275 real (c_float) :: x_coord = 0
276 real (c_float) :: y_coord = 0
277 integer (c_int) :: indx_start = 0
278 integer (c_int) :: indx_end = 0
279 end type cell_col_row_t
280
281 type ( cell_col_row_t ), allocatable :: dump(:)
282 type ( cell_col_row_t ), allocatable :: temp_dump(:)
283
284 ! creating several module-level globals
285 type (model_domain_t), public :: model
286
287 real (c_float), allocatable, public :: rooting_depth_max(:,:)
288
290
292
293contains
294
295 !
296 ! current concept:
297 !
298 ! The only 2-D array is the array that contains the mask of active cells.
299 !
300 ! All remaining state variables and ancillary variables are kept in 1-D vectors
301 ! that are PACK-ed and UNPACK-ed as needed by i/o routines. This is cumbersome for fully
302 ! active grids, but should amount to significant memory and processing savings when running
303 ! SWB for, say, an island domain.
304 !
305
306 subroutine set_output_directory_sub( this, output_dir_name )
307
308 class(model_domain_t), intent(inout) :: this
309 character (len=*), intent(in) :: output_dir_name
310
311 this%output_directory_name = output_dir_name
312
313 end subroutine set_output_directory_sub
314
315!--------------------------------------------------------------------------------------------------
316
318
319 class(model_domain_t), intent(inout) :: this
320
321 !> initialize procedure pointers such that the default methods are in place
322 !! this routine necessary because Intel compiler does not support initialization
323 !! of defined type procedure pointers within the defined type definition
324 this%init_interception => model_initialize_interception_bucket
325 this%init_runoff => model_initialize_runoff_curve_number
326 this%init_reference_et => model_initialize_et_hargreaves
328 this%init_routing => model_initialize_routing_d8
330 this%init_snowfall => model_initialize_snowfall_original
331 this%init_snowmelt => model_initialize_snowmelt_original
332 this%init_precipitation_data => model_initialize_precip_normal
333 this%init_fog => model_initialize_fog_none
334 this%init_irrigation => model_initialize_irrigation_none
335 this%init_direct_net_infiltration => model_initialize_direct_net_infiltration_gridded
336 this%init_direct_soil_moisture => model_initialize_direct_soil_moisture_none
337 this%update_landuse_codes => model_update_landuse_codes_static
338 this%init_GDD => model_initialize_gdd
339 this%init_growing_season => model_initialize_growing_season
341 this%init_crop_coefficient => model_initialize_crop_coefficient_none
342 this%calc_interception => model_calculate_interception_bucket
343 this%update_crop_coefficient => model_update_crop_coefficient_none
344 this%update_irrigation_mask => model_update_irrigation_mask
345
346 this%init_rooting_depth => model_initialize_rooting_depth_none
347 this%update_rooting_depth => model_update_rooting_depth_none
348
349 this%init_continuous_frozen_ground_index => model_initialize_continuous_frozen_ground_index
350 this%calc_continuous_frozen_ground_index => model_calculate_continuous_frozen_ground_index
351
352 this%init_maximum_net_infiltration => model_initialize_maximum_net_infiltration_gridded
353 this%calc_maximum_net_infiltration => model_calculate_maximum_net_infiltration_gridded
354
355 this%calc_runoff => model_calculate_runoff_curve_number
356
357 this%calc_reference_et => model_calculate_et_hargreaves
358 this%calc_routing => model_calculate_routing_d8
359
361 this%calc_snowfall => model_calculate_snowfall_original
362 this%calc_snowmelt => model_calculate_snowmelt_original
363 this%calc_fog => model_calculate_fog_none
364 this%calc_irrigation => model_calculate_irrigation_none
365 this%calc_GDD => model_calculate_gdd
366 this%update_growing_season => model_update_growing_season
367 this%calc_direct_net_infiltration => model_calculate_direct_net_infiltration_none
368 this%calc_direct_soil_moisture => model_calculate_direct_soil_moisture_none
369
370 this%output_irrigation => model_output_irrigation_none
371 this%dump_variables => model_dump_variables_none
372
374 this%get_precipitation_data => model_get_precip_normal
375 this%get_minimum_air_temperature_data => model_get_minimum_air_temperature_normal
376 this%get_maximum_air_temperature_data => model_get_maximum_air_temperature_normal
377 this%calculate_mean_air_temperature => model_calculate_mean_air_temperature
378 this%calculate_range_in_air_temperature => model_calculate_range_in_air_temperature
379 this%calc_climatic_water_deficit => model_calculate_climatic_water_deficit
380
382
383!--------------------------------------------------------------------------------------------------
384
385 subroutine initialize_grid_sub(this, iNumCols, iNumRows, dX_ll, dY_ll, dGridCellSize )
386
387 class(model_domain_t), intent(inout) :: this
388 integer (c_int), intent(in) :: iNumCols
389 integer (c_int), intent(in) :: iNumRows
390 real (c_double), intent(in) :: dX_ll
391 real (c_double), intent(in) :: dY_ll
392 real (c_double), intent(in) :: dGridcellSize
393
394 ! [ LOCALS ]
395 integer (c_int) :: iStat
396
397 this%number_of_columns = inumcols
398 this%number_of_rows = inumrows
399 this%X_ll = dx_ll
400 this%Y_ll = dy_ll
401 this%gridcellsize = dgridcellsize
402
403 allocate(this%active(inumcols, inumrows), stat=istat )
404 call assert (istat == 0, "Problem allocating memory", __file__, __line__)
405
406 allocate(this%nodata_fill_value(inumcols, inumrows), stat=istat )
407 call assert (istat == 0, "Problem allocating memory", __file__, __line__)
408
409 allocate(this%array_output(inumcols, inumrows), stat=istat )
410 call assert (istat == 0, "Problem allocating memory", __file__, __line__)
411
412 allocate(this%col_num_2D(inumcols, inumrows), stat=istat )
413 call assert (istat == 0, "Problem allocating memory", __file__, __line__)
414
415 allocate(this%row_num_2D(inumcols, inumrows), stat=istat )
416 call assert (istat == 0, "Problem allocating memory", __file__, __line__)
417
418 this%pGrdOut => grid_createsimple( inx=inumcols, iny=inumrows, &
419 rx0=dx_ll, ry0=dy_ll, rgridcellsize=dgridcellsize, &
420 idatatype=grid_datatype_real )
421
422 this%nodata_fill_value = nc_fill_float
423
424 end subroutine initialize_grid_sub
425
426!--------------------------------------------------------------------------------------------------
427
428 subroutine initialize_arrays_sub(this)
429
430 class(model_domain_t), intent(inout) :: this
431
432 ! [ LOCALS ]
433 integer (c_int) :: iCount
434 integer (c_int) :: iIndex
435 integer (c_int) :: iStat(72)
436
437 icount = count( this%active )
438 istat = 0
439
440 allocate( this%landuse_code(icount), stat=istat(1) )
441 allocate( this%landuse_index(icount), stat=istat(2) )
442 allocate( this%soil_group(icount), stat=istat(3) )
443 allocate( this%num_upslope_connections(icount), stat=istat(4) )
444 allocate( this%sum_upslope_cells(icount), stat=istat(5) )
445 allocate( this%awc(icount), stat=istat(6) )
446 allocate( this%latitude(icount), stat=istat(7) )
447 allocate( this%reference_ET0(icount), stat=istat(8) )
448 allocate( this%actual_ET(icount), stat=istat(9) )
449 allocate( this%inflow(icount), stat=istat(10))
450 allocate( this%runon(icount), stat=istat(11) )
451 allocate( this%runoff(icount), stat=istat(12) )
452 allocate( this%outflow(icount), stat=istat(13) )
453 allocate( this%infiltration(icount), stat=istat(14) )
454 allocate( this%snowfall(icount), stat=istat(15) )
455 allocate( this%snowmelt(icount), stat=istat(16) )
456 allocate( this%interception(icount), stat=istat(17) )
457 allocate( this%rainfall(icount), stat=istat(18) )
458 allocate( this%interception_storage(icount), stat=istat(19) )
459 allocate( this%interception_storage_max(icount), stat=istat(20) )
460 allocate( this%snow_storage(icount), stat=istat(21) )
461 allocate( this%soil_storage(icount), stat=istat(22) )
462 allocate( this%soil_storage_max(icount), stat=istat(23) )
463 allocate( this%net_infiltration(icount), stat=istat(24) )
464 allocate( this%fog(icount), stat=istat(25) )
465 allocate( this%irrigation(icount), stat=istat(26) )
466 allocate( this%sort_order(icount), stat=istat(27) )
467 allocate( this%runoff_outside( icount ), stat=istat(28) )
468 allocate( this%pervious_fraction( icount ), stat=istat(29) )
469 allocate( this%surface_storage( icount ), stat=istat(30) )
470 allocate( this%surface_storage_excess( icount ), stat=istat(31) )
471 allocate( this%surface_storage_max( icount ), stat=istat(32) )
472 allocate( this%storm_drain_capture( icount ), stat=istat(33) )
473 allocate( this%canopy_cover_fraction( icount ), stat=istat(34) )
474 allocate( this%crop_coefficient_kcb( icount ), stat=istat(35) )
475 allocate( this%potential_snowmelt( icount ), stat=istat(36) )
476 allocate( this%continuous_frozen_ground_index( icount ), stat=istat(37) )
477 allocate( this%cfgi_lower_limit( icount), stat=istat(38) )
478 allocate( this%cfgi_upper_limit( icount), stat=istat(39) )
479 allocate( this%rooting_depth_max( icount ), stat=istat(40) )
480 allocate( this%current_rooting_depth( icount ), stat=istat(41) )
481 allocate( this%current_plant_height( icount ), stat=istat(42) )
482 allocate( this%polygon_id( icount ), stat=istat(43) )
483 allocate( this%actual_et_soil( icount ), stat=istat(44) )
484 allocate( this%actual_et_impervious( icount ), stat=istat(45) )
485 allocate( this%actual_et_interception( icount ), stat=istat(46) )
486 allocate( this%adjusted_depletion_fraction_p( icount ), stat=istat(47) )
487 allocate( this%crop_etc( icount ), stat=istat(48) )
488 allocate( this%direct_net_infiltration( icount ), stat=istat(49) )
489 allocate( this%direct_soil_moisture( icount ), stat=istat(50) )
490 allocate( this%number_of_days_since_planting( icount ), stat=istat(51) )
491 allocate( this%col_num_1D( icount ), stat=istat(52) )
492 allocate( this%row_num_1D( icount ), stat=istat(53) )
493 allocate( this%it_is_growing_season( icount ), stat=istat(54) )
494 allocate( this%curve_num_adj( icount ), stat=istat(55) )
495 allocate( this%rejected_net_infiltration( icount ), stat=istat(56) )
496 allocate( this%evap_reduction_coef_kr( icount ), stat=istat(57) )
497 allocate( this%surf_evap_coef_ke( icount ), stat=istat(58) )
498 allocate( this%plant_stress_coef_ks( icount ), stat=istat(59) )
499 allocate( this%total_available_water_taw( icount ), stat=istat(60) )
500 allocate( this%readily_available_water_raw( icount ), stat=istat(61) )
501 allocate( this%bare_soil_evap( icount ), stat=istat(62) )
502 allocate( this%fraction_exposed_and_wetted_soil( icount ), stat=istat(63) )
503 allocate( this%delta_soil_storage( icount ), stat=istat(64) )
504 allocate( this%soil_moisture_deficit( icount ), stat=istat(65) )
505 allocate( this%net_rainfall( icount ), stat=istat(66) )
506 allocate( this%net_snowfall( icount ), stat=istat(67) )
507 allocate( this%evaporable_water_storage( icount ), stat=istat(68) )
508 allocate( this%evaporable_water_deficit( icount ), stat=istat(69) )
509 allocate( this%irrigation_mask( icount ), stat=istat(70) )
510 allocate( this%tmax_minus_tmin( icount ), stat=istat(71) )
511 allocate( this%climatic_deficit( icount ), stat=istat(72) )
512
513 do iindex = 1, ubound( istat, 1)
514 if ( istat( iindex ) /= 0 ) call warn("INTERNAL PROGRAMMING ERROR" &
515 //"--Problem allocating memory; iIndex=" &
516 //ascharacter(iindex), __file__, __line__ )
517 enddo
518
519 if (any( istat /= 0) ) call die ( "Unable to allocate memory for one or more arrays.", &
520 __file__, __line__ )
521
522 this%landuse_code = 0_c_int
523 this%landuse_index = 0_c_int
524 this%soil_group = 0_c_int
525 this%num_upslope_connections = 0_c_int
526 this%sum_upslope_cells = 0_c_int
527 this%awc = 0.0_c_float
528 this%latitude = 0.0_c_float
529 this%reference_ET0 = 0.0_c_float
530 this%actual_ET = 0.0_c_double
531 this%bare_soil_evap = 0.0_c_float
532 this%inflow = 0.0_c_float
533 this%runon = 0.0_c_float
534 this%runoff = 0.0_c_float
535 this%outflow = 0.0_c_float
536 this%infiltration = 0.0_c_float
537 this%snowfall = 0.0_c_float
538 this%net_snowfall = 0.0_c_float
539 this%snowmelt = 0.0_c_float
540
541 this%interception = 0.0_c_float
542 this%rainfall = 0.0_c_float
543 this%net_rainfall = 0.0_c_float
544 this%interception_storage = 0.0_c_float
545 this%interception_storage_max = 0.0_c_float
546 this%snow_storage = 0.0_c_float
547 this%soil_storage = 0.0_c_double
548 this%soil_storage_max = 0.0_c_float
549 this%delta_soil_storage = 0.0_c_float
550 this%soil_moisture_deficit = 0.0_c_float
551
552 this%net_infiltration = 0.0_c_float
553 this%rejected_net_infiltration = 0.0_c_float
554 this%fog = 0.0_c_float
555 this%irrigation = 0.0_c_float
556 this%curve_num_adj = 0.0_c_float
557 this%runoff_outside = 0.0_c_float
558 this%pervious_fraction = 1.0_c_float ! note: default is 100% pervious area
559 this%surface_storage = 0.0_c_float
560 this%surface_storage_excess = 0.0_c_float
561 this%surface_storage_max = 0.0_c_float
562 this%storm_drain_capture = 0.0_c_float
563 this%canopy_cover_fraction = 0.0_c_float
564 this%crop_coefficient_kcb = 0.0_c_float
565 this%potential_snowmelt = 0.0_c_float
566 this%continuous_frozen_ground_index = 0.0_c_float
567 this%cfgi_lower_limit = 0.0_c_float
568 this%cfgi_upper_limit = 0.0_c_float
569 this%rooting_depth_max = 0.0_c_float
570 this%current_rooting_depth = 0.0_c_float
571 this%current_plant_height = 0.0_c_float
572 this%polygon_id = 0_c_int
573 this%actual_et_soil = 0.0_c_double
574 this%actual_et_impervious = 0.0_c_double
575 this%actual_et_interception = 0.0_c_double
576 this%adjusted_depletion_fraction_p = 0.0_c_float
577 this%crop_etc = 0.0_c_float
578 this%direct_net_infiltration = 0.0_c_float
579 this%direct_soil_moisture = 0.0_c_float
580 this%number_of_days_since_planting = 0_c_int
581 this%evap_reduction_coef_kr = 1.0_c_float
582 this%surf_evap_coef_ke = 0.0_c_float
583 this%plant_stress_coef_ks = 1.0_c_float
584 this%total_available_water_taw = 0.0_c_float
585 this%readily_available_water_raw = 0.0_c_float
586 this%fraction_exposed_and_wetted_soil = 0.0_c_float
587 this%evaporable_water_storage = 0.0_c_float
588 this%evaporable_water_deficit = 0.0_c_float
589 this%it_is_growing_season = false
590 this%irrigation_mask = 1.0_c_float
591 this%tmax_minus_tmin = 0.0_c_float
592 this%climatic_deficit = 0.0_c_float
593
594 do iindex=1, icount
595 this%sort_order( iindex ) = iindex
596 enddo
597
598 end subroutine initialize_arrays_sub
599
600!--------------------------------------------------------------------------------------------------
601
603
604 class(model_domain_t), intent(inout) :: this
605
606 ! [ LOCALS ]
607 integer (c_int) :: row_num, col_num
608 integer (c_int) :: status
609
610 do row_num=lbound( this%row_num_2D, 2), ubound( this%row_num_2D, 2)
611 this%row_num_2D( :, row_num ) = row_num
612 enddo
613
614 do col_num=lbound( this%col_num_2D, 1), ubound( this%col_num_2D, 1 )
615 this%col_num_2D( col_num, : ) = col_num
616 enddo
617
618 this%col_num_1D = pack( this%col_num_2D, this%active )
619 this%row_num_1D = pack( this%row_num_2D, this%active )
620
621 deallocate( this%col_num_2D, stat=status )
622 deallocate( this%row_num_2D, stat=status )
623
625
626!--------------------------------------------------------------------------------------------------
627
628 function row_column_to_index_fn( this, col_num, row_num ) result( indexval )
629
630 class(model_domain_t), intent(inout) :: this
631 integer (c_int), intent(in) :: col_num
632 integer (c_int), intent(in) :: row_num
633 integer (c_int) :: indexval
634
635 ! [ LOCALS ]
636 logical (c_bool) :: found_match
637
638 found_match = false
639
640 do indexval=lbound( this%col_num_1D, 1 ), ubound( this%col_num_1D, 1 )
641
642 if ( ( this%col_num_1D( indexval ) == col_num ) &
643 .and. ( this%row_num_1D( indexval ) == row_num ) ) then
644 found_match = true
645 exit
646 endif
647
648 enddo
649
650 if ( .not. found_match ) indexval = -9999
651
652 end function row_column_to_index_fn
653
654!--------------------------------------------------------------------------------------------------
655
656 subroutine initialize_methods_sub(this)
657
658 class(model_domain_t), intent(inout) :: this
659
660 call this%init_interception
661
662 call this%init_snowfall
663
664 call this%init_rooting_depth
665
666 call this%init_snowmelt
667
668 call this%init_fog
669
670 call this%init_precipitation_data
671
672 call this%init_runoff
673
674 call this%init_soil_storage_max
675
676 call this%init_routing
677
678 call this%init_actual_et
679
680 call this%init_reference_et
681
682 call this%init_GDD
683
684 call this%init_irrigation
685
686 call this%init_direct_net_infiltration
687
688 call this%init_direct_soil_moisture
689
690 call this%init_maximum_net_infiltration
691
692 call this%init_crop_coefficient
693
694 end subroutine initialize_methods_sub
695
696!--------------------------------------------------------------------------------------------------
697
698 subroutine set_inactive_cells_sub(this)
699
701
702 class(model_domain_t), intent(inout) :: this
703 type (DATA_CATALOG_ENTRY_T), pointer :: pHSG
704 type (DATA_CATALOG_ENTRY_T), pointer :: pLULC
705 type (DATA_CATALOG_ENTRY_T), pointer :: pAWC
706 type (DATA_CATALOG_ENTRY_T), pointer :: pSoil_Storage_Max
707 type (DATA_CATALOG_ENTRY_T), pointer :: pD8_FLOWDIR
708 type ( GENERAL_GRID_T ), pointer :: pTempGrd
709
710 plulc => dat%find("LAND_USE")
711 phsg => dat%find("HYDROLOGIC_SOILS_GROUP")
712 pawc => dat%find("AVAILABLE_WATER_CONTENT")
713 psoil_storage_max => dat%find("SOIL_STORAGE_MAX")
714 pd8_flowdir => dat%find("FLOW_DIRECTION")
715
716 if( .not. associated( pawc ) ) pawc => dat%find("AVAILABLE_WATER_CONTENT")
717
718 if ( .not. associated(phsg) ) &
719 call die("INTERNAL PROGRAMMING ERROR: attempted use of NULL pointer", __file__, __line__)
720
721 if ( .not. associated(phsg%pGrdBase) ) &
722 call die("INTERNAL PROGRAMMING ERROR: attempted use of NULL pointer", __file__, __line__)
723
724 if ( .not. allocated(phsg%pGrdBase%iData) ) &
725 call die("INTERNAL PROGRAMMING ERROR: attempted use of UNALLOCATED variable", __file__, __line__)
726
727! if ( .not. associated(pAWC) ) &
728! call die("INTERNAL PROGRAMMING ERROR: attempted use of NULL pointer", __FILE__, __LINE__)
729
730! if ( .not. associated(pAWC%pGrdBase) ) &
731! call die("INTERNAL PROGRAMMING ERROR: attempted use of NULL pointer", __FILE__, __LINE__)
732
733! if ( .not. allocated(pAWC%pGrdBase%rData) ) &
734! call die("INTERNAL PROGRAMMING ERROR: attempted use of UNALLOCATED variable", __FILE__, __LINE__)
735
736 if ( .not. associated(plulc) ) &
737 call die("INTERNAL PROGRAMMING ERROR: attempted use of NULL pointer", __file__, __line__)
738
739 if ( .not. associated(plulc%pGrdBase) ) &
740 call die("INTERNAL PROGRAMMING ERROR: attempted use of NULL pointer", __file__, __line__)
741
742 if ( .not. allocated(plulc%pGrdBase%iData) ) &
743 call die("INTERNAL PROGRAMMING ERROR: attempted use of UNALLOCATED variable", __file__, __line__)
744
745 this%active = .true._c_bool
746
747 if ( associated( pd8_flowdir ) ) then
748
749 call pd8_flowdir%getvalues()
750 where ( pd8_flowdir%pGrdBase%iData < 0 ) this%active = .false._c_bool
751
752 endif
753
754 ! this is the 'normal'case, where user specifies both a maximum rooting depth
755 ! in the lookup table and a grid of available water content (in/ft)
756 if ( associated( pawc) ) then
757
758 where ( ( phsg%pGrdBase%iData < 1 ) &
759 .or. ( plulc%pGrdBase%iData < 0 ) &
760 .or. ( pawc%pGrdBase%rData < 0.0 ) )
761
762 this%active = .false._c_bool
763
764 end where
765
766 ! user specifies both a maximum rooting depth and available water content (in/ft)
767 ! in a lookup table
768 elseif ( allocated( available_water_content ) ) then
769
770 where ( ( phsg%pGrdBase%iData < 1 ) &
771 .or. ( plulc%pGrdBase%iData < 0 ) &
772 .or. ( available_water_content < 0.0 ) )
773
774 this%active = .false._c_bool
775
776 end where
777
778 ! user specifies maximum soil storage (inches) directly via grid
779 elseif ( associated( psoil_storage_max ) ) then
780
781 call psoil_storage_max%getvalues()
782
783 where ( ( phsg%pGrdBase%iData < 1 ) &
784 .or. ( plulc%pGrdBase%iData < 0 ) &
785 .or. ( psoil_storage_max%pGrdBase%rData < 0.0 ) )
786
787 this%active = .false._c_bool
788
789 end where
790
791 else
792
793 call die( "Failed to find gridded or tabular data to use in initializing " &
794 //"available water capacity or soil storage.", &
795 __file__, __line__ )
796
797 endif
798
799 call logs%write(ascharacter(count(this%active))//" cells are currently active out of a total of " &
800 //ascharacter(size(this%active)), ilinesbefore=1, ilinesafter=1, iloglevel=log_all)
801
802 ! output a simple ASCII grid depicting final active/non-active cell status
803 ptempgrd => grid_create( inx=this%number_of_columns, iny=this%number_of_rows, &
804 rx0=this%X_ll, ry0=this%Y_ll, &
805 rgridcellsize=this%gridcellsize, idatatype=grid_datatype_int )
806
807 where ( this%active )
808 ptempgrd%iData = 1_c_int
809 elsewhere
810 ptempgrd%iData = 0_c_int
811 endwhere
812
813 call grid_writearcgrid( sfilename="Active_and_inactive_gridcells.asc", pgrd=ptempgrd )
814 call grid_destroy( ptempgrd )
815
816 end subroutine set_inactive_cells_sub
817
818!--------------------------------------------------------------------------------------------------
819
821
822 ! [ LOCALS ]
823 type (data_catalog_entry_t), pointer :: plulc
824 character (len=10) :: date_str
825
826 plulc => dat%find("LAND_USE")
827
828 if ( associated(plulc) ) then
829
830 if (plulc%iSourceDataForm == dynamic_grid) then
831
832 model%update_landuse_codes => model_update_landuse_codes_dynamic
833
834 call plulc%getvalues( sim_dt%curr )
835
836 if ( plulc%lGridHasChanged ) then
837 date_str = sim_dt%curr%prettydate()
838 call grid_writearcgrid("Landuse_land_cover__as_read_into_SWB__" &
839 //trim(date_str)//".asc", plulc%pGrdBase )
840 endif
841
842 else
843
844 call plulc%getvalues()
845 call grid_writearcgrid("Landuse_land_cover__as_read_into_SWB.asc", plulc%pGrdBase )
846
847 endif
848
849 else
850
851 call warn(smessage="LAND_USE dataset is flawed or missing.", lfatal=true, &
852 iloglevel = log_all, shints="Check to see that a valid path and filename have" &
853 //" been ~included in the control file for the LAND_USE dataset.", &
854 lecho = true )
855
856 endif
857
858 end subroutine read_landuse_codes
859
860!--------------------------------------------------------------------------------------------------
861
862 !> Match landuse codes from table with those contained in the gridded landuse.
863 !!
864 !! This routine loops through all known
865
867
868 ! [ LOCALS ]
869 integer (c_int) :: iindex
870 integer (c_int), allocatable :: ilandusecodes(:)
871 type (data_catalog_entry_t), pointer :: plulc
872 integer (c_int) :: iindex2
873 integer (c_int) :: icount
874 logical (c_bool) :: lmatch
875 type (fstring_list_t) :: sllist
876
877 call sllist%append("LU_Code")
878 call sllist%append("LU_code")
879 call sllist%append("Landuse_Code")
880 call sllist%append("LULC_Code")
881
882 !> Determine how many landuse codes are present
883 call params%get_parameters( slkeys=sllist, ivalues=ilandusecodes, lfatal=true )
884
885 if (ubound(ilandusecodes,1) <= 1) then
886 call warn(smessage="A lookup table with a only a single entry will not work with swb2.", &
887 shints="Please use a lookup table with more than a single line of data.", &
888 lfatal=true)
889 endif
890
891 ! obtain a pointer to the LAND_USE grid
892 plulc => dat%find("LAND_USE")
893
894 if ( associated(plulc) ) then
895
896 if (associated( plulc%pGrdBase) ) then
897 model%landuse_code = pack( plulc%pGrdBase%iData, model%active )
898 else
899 call die("INTERNAL PROGRAMMING ERROR: attempted use of NULL pointer", __file__, __line__)
900 endif
901 else
902 call die("Attempted use of NULL pointer. Failed to find LAND_USE data element.", &
903 __file__, __line__)
904 endif
905
906 ! setting this to a value that is likely valid; if this is set to a negative value, a landuse
907 ! code that is present in the grid but not in the lookup table will trigger a fatal error, however,
908 ! processing will continue until a bounds error is triggered somewhere else in the code,
909 model%landuse_index = -9999
910
911 icount = 0
912
913 ! only run through matching process if we have found a LU_Code entry in the
914 ! parameter dictionary
915
916 if ( all( ilandusecodes >= 0 ) ) then
917
918 do iindex = 1, ubound(model%landuse_code,1)
919
920 lmatch = false
921
922 do iindex2=1, ubound(ilandusecodes, 1)
923
924 if (model%landuse_code(iindex) == ilandusecodes(iindex2) ) then
925 model%landuse_index(iindex) = iindex2
926 icount = icount + 1
927 lmatch = true
928 exit
929 endif
930
931 enddo
932
933 if ( .not. lmatch ) then
934 call warn(smessage="Failed to match landuse code "//ascharacter(model%landuse_code(iindex) ) &
935 //" with a corresponding landuse code from lookup tables.", &
936 shints="Make sure your lookup table(s) have landuse codes corresponding to all values in " &
937 //"the land-use grid.", lfatal=true, iloglevel=log_all, lecho=true)
938 ! we are setting this value to a valid value. this should not cause problems with any
939 ! calculations because we have already thrown a fatal error
940 model%landuse_index(iindex) = 1
941 endif
942 enddo
943
944 call logs%write("Matches were found between landuse grid value and table value for " &
945 //ascharacter(icount)//" cells out of a total of "//ascharacter(ubound(model%landuse_code,1))//" active cells.", &
946 ilinesbefore=1, ilinesafter=1, iloglevel=log_all)
947
948 call sllist%clear()
949
950 endif
951
952 ! if we have more than one cell for which an index value could not be assigned, trigger fatal error
953 if ( count(model%landuse_index < 0) > 0 ) then
954 call warn(ascharacter(count(model%landuse_index < 0))//" landuse codes could not be " &
955 //" assigned a landuse index value.", lfatal=true, shints="Make sure that you have an " &
956 //"entry in the landuse lookup table for each unique code contained in your landuse grid." )
957 endif
958
959
960 end subroutine initialize_landuse_codes
961
962!--------------------------------------------------------------------------------------------------
963
964! subroutine read_in_available_water_content_sub( this )
965
966! class (MODEL_DOMAIN_T), intent(inout) :: this
967
968! ! [ LOCALS ]
969! integer (c_int) :: iStat
970! integer (c_int) :: iIndex
971! type (DATA_CATALOG_ENTRY_T), pointer :: pAWC
972
973! pAWC => DAT%find("AVAILABLE_WATER_CONTENT")
974
975! if ( associated(pAWC) ) then
976
977! call pAWC%getvalues()
978! call grid_WriteArcGrid("Available_Water_Content__as_read_in_by_SWB.asc", pAWC%pGrdBase )
979
980! else
981
982! call warn(sMessage="AVAILABLE_WATER_CONTENT dataset is flawed or missing.", lFatal=FALSE, &
983! iLogLevel = LOG_ALL, sHints="Check to see that a valid path and filename have" &
984! //" been ~included in the control file for the AVAILABLE_WATER_CONTENT dataset.", &
985! lEcho = TRUE )
986
987! endif
988
989! end subroutine read_in_available_water_content_sub
990
991!--------------------------------------------------------------------------------------------------
992
993 subroutine get_weather_data(this)
994
995 class(model_domain_t), intent(inout) :: this
996
997 ! [ LOCALS ]
998 integer (c_int) :: iJulianDay
999 integer (c_int) ::iMonth
1000 integer (c_int) ::iDay
1001 integer (c_int) ::iYear
1002
1003 associate( dt => sim_dt%curr )
1004
1005 ijulianday = dt%getJulianDay()
1006 imonth = asint( dt%iMonth )
1007 iday = asint( dt%iDay )
1008 iyear = dt%iYear
1009
1010
1011 ! the following statements process the raw data in order to get it into the
1012 ! right units or properly pack the data
1013
1014 call this%get_precipitation_data()
1015 call this%get_minimum_air_temperature_data()
1016 call this%get_maximum_air_temperature_data()
1017
1018 call this%calculate_mean_air_temperature()
1019 call this%calculate_range_in_air_temperature()
1020
1021 end associate
1022
1023 end subroutine get_weather_data
1024
1025!--------------------------------------------------------------------------------------------------
1026
1028
1029 class(model_domain_t), intent(inout) :: this
1030
1031 if (.not. associated( this%init_interception) ) &
1032 call die("INTERNAL PROGRAMMING ERROR--Null procedure pointer.", __file__, __line__ )
1033 if (.not. associated( this%calc_interception) ) &
1034 call die("INTERNAL PROGRAMMING ERROR--Null procedure pointer.", __file__, __line__ )
1035
1036 if (.not. associated( this%init_irrigation) ) &
1037 call die("INTERNAL PROGRAMMING ERROR--Null procedure pointer.", __file__, __line__ )
1038 if (.not. associated( this%calc_irrigation) ) &
1039 call die("INTERNAL PROGRAMMING ERROR--Null procedure pointer.", __file__, __line__ )
1040
1041 if (.not. associated( this%init_runoff) ) &
1042 call die("INTERNAL PROGRAMMING ERROR--Null procedure pointer.", __file__, __line__ )
1043 if (.not. associated( this%calc_runoff) ) &
1044 call die("INTERNAL PROGRAMMING ERROR--Null procedure pointer.", __file__, __line__ )
1045
1046 if (.not. associated( this%init_reference_et) ) &
1047 call die("INTERNAL PROGRAMMING ERROR--Null procedure pointer.", __file__, __line__ )
1048 if (.not. associated( this%calc_reference_et) ) &
1049 call die("INTERNAL PROGRAMMING ERROR--Null procedure pointer.", __file__, __line__ )
1050
1051 if (.not. associated( this%init_snowmelt) ) &
1052 call die("INTERNAL PROGRAMMING ERROR--Null procedure pointer.", __file__, __line__ )
1053 if (.not. associated( this%calc_snowmelt) ) &
1054 call die("INTERNAL PROGRAMMING ERROR--Null procedure pointer.", __file__, __line__ )
1055
1056 if (.not. associated( this%init_snowfall) ) &
1057 call die("INTERNAL PROGRAMMING ERROR--Null procedure pointer.", __file__, __line__ )
1058 if (.not. associated( this%calc_snowfall) ) &
1059 call die("INTERNAL PROGRAMMING ERROR--Null procedure pointer.", __file__, __line__ )
1060
1061 if (.not. associated( this%init_GDD) ) &
1062 call die("INTERNAL PROGRAMMING ERROR--Null procedure pointer.", __file__, __line__ )
1063 if (.not. associated( this%calc_GDD) ) &
1064 call die("INTERNAL PROGRAMMING ERROR--Null procedure pointer.", __file__, __line__ )
1065
1066 if (.not. associated( this%init_routing) ) &
1067 call die("INTERNAL PROGRAMMING ERROR--Null procedure pointer.", __file__, __line__ )
1068 if (.not. associated( this%calc_routing) ) &
1069 call die("INTERNAL PROGRAMMING ERROR--Null procedure pointer.", __file__, __line__ )
1070
1071 if (.not. associated( this%init_direct_net_infiltration) ) &
1072 call die("INTERNAL PROGRAMMING ERROR--Null procedure pointer.", __file__, __line__ )
1073 if (.not. associated( this%calc_direct_net_infiltration) ) &
1074 call die("INTERNAL PROGRAMMING ERROR--Null procedure pointer.", __file__, __line__ )
1075
1076 if (.not. associated( this%init_soil_storage_max) ) &
1077 call die("INTERNAL PROGRAMMING ERROR--Null procedure pointer.", __file__, __line__ )
1078
1079 if (.not. associated( this%get_precipitation_data ) ) &
1080 call die("INTERNAL PROGRAMMING ERROR--Null procedure pointer.", __file__, __line__ )
1081
1082 if (.not. associated( this%get_minimum_air_temperature_data ) ) &
1083 call die("INTERNAL PROGRAMMING ERROR--Null procedure pointer.", __file__, __line__ )
1084
1085 if (.not. associated( this%get_maximum_air_temperature_data ) ) &
1086 call die("INTERNAL PROGRAMMING ERROR--Null procedure pointer.", __file__, __line__ )
1087
1088 end subroutine preflight_check_method_pointers
1089
1090 !------------------------------------------------------------------------------------------------
1091
1092 subroutine set_method_pointers_sub(this, sCmdText, argv_list )
1093
1094 class(model_domain_t), intent(inout) :: this
1095 character (len=*), intent(in) :: sCmdText
1096 type (FSTRING_LIST_T) :: argv_list
1097
1098 ! [ LOCALS ]
1099 integer (c_int) :: indx
1100 integer (c_int) :: iostat
1101 integer (c_int) :: unitnum
1102 character (len=256) :: filename
1103 character (len=:), allocatable :: Method_Name
1104 character (len=:), allocatable :: modifier_text
1105 character (len=:), allocatable :: dump_file_prefix
1106 character (len=:), allocatable :: temp_str
1107 integer (c_int) :: col, row
1108 integer (c_int) :: indx_start, indx_end
1109 real (c_double) :: xcoord, ycoord
1110 logical (c_bool) :: row_col_num_are_valid
1111 logical (c_bool) :: coordinates_are_valid
1112 logical (c_bool) :: indices_are_valid
1113
1114 method_name = argv_list%get(1)
1115
1116 if ( scmdtext .containssimilar. "INTERCEPTION" ) then
1117
1118 if ( (method_name .strapprox. "BUCKET") .or. (method_name .strapprox. "HORTON")) then
1119
1120 this%init_interception => model_initialize_interception_bucket
1121 this%calc_interception => model_calculate_interception_bucket
1122
1123 call logs%WRITE( "==> BUCKET/HORTON INTERCEPTION submodel selected.", iloglevel = log_all, lecho = false )
1124
1125 elseif ( method_name .strapprox. "GASH" ) then
1126
1127 this%init_interception => model_initialize_interception_gash
1128 this%calc_interception => model_calculate_interception_gash
1129
1130 call logs%WRITE( "==> GASH INTERCEPTION submodel selected.", iloglevel = log_all, lecho = false )
1131
1132 else
1133
1134 call warn("Your control file specifies an unknown or unsupported INTERCEPTION method.", &
1135 lfatal = true, iloglevel = log_all, lecho = true )
1136
1137 endif
1138
1139 elseif ( scmdtext .containssimilar. "RUNOFF" ) then
1140
1141 if ( ( method_name .strapprox. "C-N" ) .or. ( method_name .strapprox. "CURVE_NUMBER" ) ) then
1142
1143 this%init_runoff => model_initialize_runoff_curve_number
1144 this%calc_runoff => model_calculate_runoff_curve_number
1145
1146 call logs%WRITE( "==> CURVE NUMBER RUNOFF submodel selected.", iloglevel = log_all, lecho = false )
1147
1148 elseif ( ( method_name .strapprox. "RUNOFF_RATIO" ) .or. ( method_name .strapprox. "MONTHLY_GRID" ) ) then
1149
1150 this%init_runoff => model_initialize_runoff_gridded_values
1151 this%calc_runoff => model_calculate_runoff_gridded_values
1152
1153 call logs%WRITE( "==> RUNOFF RATIO submodel selected.", iloglevel = log_all, lecho = false )
1154
1155 else
1156
1157 call warn("Your control file specifies an unknown or unsupported RUNOFF method.", &
1158 lfatal = true, iloglevel = log_all, lecho = true )
1159
1160 endif
1161
1162 elseif ( scmdtext .containssimilar. "ROOTING" ) then
1163
1164 if ( ( method_name .strapprox. "DYNAMIC" ) .or. ( method_name .strapprox. "FAO_56" ) &
1165 .or. ( method_name .strapprox. "FAO-56" ) .or. ( method_name .strapprox. "FAO56" ) ) then
1166
1167 this%init_rooting_depth => model_initialize_rooting_depth_fao56
1168 this%update_rooting_depth => model_update_rooting_depth_fao56
1169 call logs%WRITE( "==> DYNAMIC rooting depth submodel selected.", iloglevel = log_all, lecho = false )
1170
1171 else
1172
1173 this%init_rooting_depth => model_initialize_rooting_depth_none
1174 this%update_rooting_depth => model_update_rooting_depth_none
1175 call logs%WRITE( "==> STATIC rooting depth submodel selected.", iloglevel = log_all, lecho = false )
1176
1177 endif
1178
1179 elseif ( scmdtext .containssimilar. "DYNAMIC_LANDUSE" ) then
1180
1181 this%update_landuse_codes => model_update_landuse_codes_dynamic
1182
1183 elseif ( scmdtext .containssimilar. "STATIC_LANDUSE" ) then
1184
1185 this%update_landuse_codes => model_update_landuse_codes_static
1186
1187 elseif ( scmdtext .containssimilar. "SNOWFALL" ) then
1188
1189 if ( ( method_name .strapprox. "ORIGINAL" ) .or. ( method_name .strapprox. "ORIGINAL_SWB_METHOD" ) ) then
1190
1191 this%init_snowfall => model_initialize_snowfall_original
1192 this%calc_snowfall => model_calculate_snowfall_original
1193
1194 call logs%WRITE( "==> ORIGINAL SNOWFALL submodel selected.", iloglevel = log_all, lecho = false )
1195
1196 elseif ( method_name .strapprox. "PRMS" ) then
1197
1198 this%init_snowfall => model_initialize_snowfall_prms
1199 this%calc_snowfall => model_calculate_snowfall_prms
1200
1201 call logs%WRITE( "==> PRMS SNOWFALL submodel selected.", iloglevel = log_all, lecho = false )
1202
1203 else
1204
1205 call warn("Your control file specifies an unknown or unsupported SNOWFALL method.", &
1206 lfatal = true, iloglevel = log_all, lecho = true )
1207
1208 endif
1209
1210 elseif ( ( scmdtext .containssimilar. "AVAILABLE_WATER_CONTENT" ) &
1211 .or. ( scmdtext .containssimilar. "AVAILABLE_WATER_CAPACITY") ) then
1212
1213 if ( ( method_name .strapprox. "TABLE" ) ) then
1214
1217
1218 call logs%WRITE( "==> TABLE method for populating AVAILABLE_WATER_CONTENT/AVAILABLE_WATER_CAPACITY selected.", &
1219 iloglevel = log_all, lecho = false )
1220
1221 elseif ( ( method_name .strapprox. "GRID" ) .or. ( method_name .strapprox. "GRIDDED" ) ) then
1222
1224 this%read_awc_data => model_read_available_water_content_gridded
1225
1226 call logs%WRITE( "==> GRIDDED VALUES method for populating AVAILABLE_WATER_CONTENT/AVAILABLE_WATER_CAPACITY selected.", &
1227 iloglevel = log_all, lecho = false )
1228
1229 else
1230
1231 call warn("Your control file specifies an unknown or unsupported AVAILABLE_WATER_CONTENT/" &
1232 //"AVAILABLE_WATER_CAPACITY method.", &
1233 lfatal = true, iloglevel = log_all, lecho = true )
1234
1235 endif
1236
1237 elseif ( scmdtext .containssimilar. "FLOW_ROUTING" ) then
1238
1239 if ( ( method_name .strapprox. "D8" ) &
1240 .or. ( method_name .strapprox. "DOWNHILL" ) ) then
1241
1242 this%init_routing => model_initialize_routing_d8
1243 this%calc_routing => model_calculate_routing_d8
1244
1245 call logs%WRITE( "==> D8 FLOW ROUTING submodel selected.", iloglevel = log_all, lecho = false )
1246
1247 else
1248
1249 this%init_routing => model_initialize_routing_none
1250 this%calc_routing => model_calculate_routing_none
1251
1252 call logs%WRITE( "==> NULL FLOW ROUTING submodel selected -- NO routing will be performed.", &
1253 iloglevel = log_all, lecho = false )
1254
1255 endif
1256
1257 elseif ( ( scmdtext .containssimilar. "CROP_COEFFICIENT" ) &
1258 .or. ( scmdtext .containssimilar. "CROP_COEF" ) ) then
1259
1260 if ( ( method_name .strapprox. "FAO56" ) &
1261 .or. ( method_name .strapprox. "FAO-56" ) &
1262 .or. ( method_name .strapprox. "FAO_56" ) ) then
1263
1264 this%init_crop_coefficient => model_initialize_crop_coefficient_fao56
1265 this%update_crop_coefficient => model_update_crop_coefficient_fao56
1267 this%update_growing_season => model_update_growing_season_crop_coefficient_fao56
1268 call logs%WRITE( "==> FAO-56 crop coefficient calculation method selected.", iloglevel = log_all, &
1269 lecho = false )
1270
1271 else
1272
1273 this%init_crop_coefficient => model_initialize_crop_coefficient_none
1274 this%update_crop_coefficient => model_update_crop_coefficient_none
1275
1276 call logs%WRITE( "==> NO crop coefficient calculation method selected. Kcb defaults to 1.0.", &
1277 iloglevel = log_all, lecho = false )
1278
1279 endif
1280
1281 elseif ( scmdtext .containssimilar. "FOG" ) then
1282
1283 if ( method_name .strapprox. "MONTHLY_GRID" ) then
1284
1285 this%init_fog => model_initialize_fog_monthly_grid
1286 this%calc_fog => model_calculate_fog_monthly_grid
1287
1288 call logs%WRITE( "==> MONTHLY_GRID FOG submodel selected.", iloglevel = log_all, lecho = false )
1289
1290 else
1291
1292 this%init_fog => model_initialize_fog_none
1293 this%calc_fog => model_calculate_fog_none
1294
1295 call logs%WRITE( "==> NULL FOG submodel selected (i.e. no fog term).", iloglevel = log_all, lecho = false )
1296
1297 endif
1298
1299 elseif ( scmdtext .containssimilar. "GROWING_DEGREE_DAY" ) then
1300
1301 if ( ( method_name .strapprox. "BASKERVILLE_EMIN" ) &
1302 .or. ( method_name .strapprox. "BE" ) &
1303 .or. ( method_name .strapprox. "SINUSOIDAL" ) ) then
1304
1305 this%init_GDD => model_initialize_gdd_be
1306 this%calc_GDD => model_calculate_gdd_be
1307 call logs%WRITE( "==> Growing degree-day (GDD) will be calculated as described " &
1308 //"in Baskerville and Emin (1969)", iloglevel = log_all, lecho = false )
1309! this%init_GDD => model_initialize_GDD
1310! this%calc_GDD => model_calculate_GDD
1311! call LOGS%WRITE( "==> THIS OPTION IS TEMPORARILY DISABLED! Growing degree-day (GDD) will be calculated using " &
1312! //"simple averaging of TMAX and TMIN.", iLogLevel = LOG_ALL, lEcho = FALSE )
1313
1314 elseif( ( method_name .strapprox. "SIMPLE" ) &
1315 .or. ( method_name .strapprox. "SIMPLE_GROWING_DEGREE_DAY" ) &
1316 .or. ( method_name .strapprox. "SIMPLE_GROWING_DEGREE-DAY") ) then
1317
1318 this%init_GDD => model_initialize_gdd
1319 this%calc_GDD => model_calculate_gdd
1320 call logs%WRITE( "==> Growing degree-day (GDD) will be calculated using " &
1321 //"simple averaging of TMAX and TMIN.", iloglevel = log_all, lecho = false )
1322
1323 elseif( ( method_name .strapprox. "MODIFIED" ) &
1324 .or. ( method_name .strapprox. "MODIFIED_GROWING_DEGREE-DAY" ) &
1325 .or. ( method_name .strapprox. "MODIFIED_GROWING_DEGREE_DAY" ) ) then
1326
1327 this%init_GDD => model_initialize_gdd
1328 this%calc_GDD => model_calculate_modified_gdd
1329 call logs%WRITE( "==> Modified growing degree-day (GDD) will be calculated using " &
1330 //"a simple averaging of TMAX and TMIN.", iloglevel = log_all, lecho = false )
1331
1332 else
1333
1334 call warn("Your control file specifies an unknown or unsupported GROWING DEGREE-DAY method.", &
1335 lfatal = true, iloglevel = log_all, lecho = true )
1336
1337 endif
1338
1339 elseif ( scmdtext .containssimilar. "IRRIGATION" ) then
1340
1341 if ( ( method_name .strapprox. "FAO56" ) &
1342 .or. ( method_name .strapprox. "FAO-56" ) &
1343 .or. ( method_name .strapprox. "FAO_56" ) ) then
1344
1345 this%init_irrigation => model_initialize_irrigation
1346 this%calc_irrigation => model_calculate_irrigation
1347
1348 call logs%WRITE( "==> IRRIGATION will be calculated and applied as needed.", iloglevel = log_all, lecho = false )
1349
1350 else
1351
1352 this%init_irrigation => model_initialize_irrigation_none
1353 this%calc_irrigation => model_calculate_irrigation_none
1354
1355 call logs%WRITE( "==> IRRIGATION will *NOT* be active.", iloglevel = log_all, lecho = false )
1356
1357 endif
1358
1359
1360 elseif ( ( scmdtext .containssimilar. "SOIL_STORAGE_MAX" ) &
1361 .or. ( scmdtext .containssimilar. "PLANT_AVAILABLE_WATER" ) ) then
1362
1363 if ( method_name .strapprox. "GRIDDED" ) then
1364
1365 this%init_soil_storage_max => model_initialize_soil_storage_max_gridded
1366
1367 call logs%WRITE( "==> SOIL_STORAGE_MAX will be read from a grid. Rooting depths will be recalculated" &
1368 //" as ~SOIL_STORAGE_MAX / AWC.", iloglevel = log_all, lecho = false )
1369
1370 else
1371
1373
1374 call logs%WRITE( "==> SOIL_STORAGE_MAX will be internally calculated from the given AWC and rooting depth values.", &
1375 iloglevel = log_all, lecho = false )
1376
1377 endif
1378
1379
1380 elseif ( scmdtext .containssimilar. "EVAPOTRANSPIRATION" ) then
1381
1382 if ( ( method_name .strapprox. "HARGREAVES" ) &
1383 .or. ( method_name .strapprox. "HARGREAVES-SAMANI" ) &
1384 .or. ( method_name .strapprox. "HARGREAVES_SAMANI" ) ) then
1385
1386 this%init_reference_et => model_initialize_et_hargreaves
1387 this%calc_reference_et => model_calculate_et_hargreaves
1388
1389 call logs%WRITE( "==> HARGREAVES-SAMANI EVAPOTRANSPIRATION submodel selected.", &
1390 iloglevel = log_all, lecho = false )
1391
1392 elseif ( ( method_name .strapprox. "JENSEN-HAISE" ) &
1393 .or. ( method_name .strapprox. "JENSEN_HAISE" ) &
1394 .or. ( method_name .strapprox. "JH" ) ) then
1395
1396 this%init_reference_et => model_initialize_et_jensen_haise
1397 this%calc_reference_et => model_calculate_et_jensen_haise
1398
1399 call logs%WRITE( "==> JENSEN_HAISE EVAPOTRANSPIRATION submodel selected.", &
1400 iloglevel = log_all, lecho = false )
1401
1402 elseif ( ( method_name .strapprox. "MONTHLY_GRID" ) &
1403 .or. ( method_name .strapprox. "MONTHLY_GRID" ) ) then
1404
1405 this%init_reference_et => model_initialize_et_monthly_grid
1406 this%calc_reference_et => model_calculate_et_monthly_grid
1407
1408 call logs%WRITE( "==> MONTHLY_GRID EVAPOTRANSPIRATION submodel selected.", &
1409 iloglevel = log_all, lecho = false )
1410
1411 elseif ( ( method_name .strapprox. "MONTHLY_ZONE" ) &
1412 .or. ( method_name .strapprox. "MONTHLY_ZONE_GRID" ) ) then
1413
1414 this%init_reference_et => model_initialize_et_monthly_zone_grid
1415 this%calc_reference_et => model_calculate_et_monthly_zone_grid
1416
1417 call logs%WRITE( "==> MONTHLY_GRID EVAPOTRANSPIRATION submodel selected.", &
1418 iloglevel = log_all, lecho = false )
1419
1420 elseif ( ( method_name .strapprox. "DAILY_GRID" ) &
1421 .or. ( method_name .strapprox. "DAILY_GRID" ) ) then
1422
1423 this%init_reference_et => model_initialize_et_daily_grid
1424 this%calc_reference_et => model_calculate_et_daily_grid
1425
1426 call logs%WRITE( "==> DAILY_GRID EVAPOTRANSPIRATION submodel selected.", &
1427 iloglevel = log_all, lecho = false )
1428
1429 else
1430
1431 call warn("Your control file specifies an unknown or unsupported EVAPOTRANSPIRATION method.", &
1432 lfatal = true, iloglevel = log_all, lecho = true )
1433
1434 endif
1435
1436 elseif ( scmdtext .containssimilar. "PRECIPITATION" ) then
1437
1438 if ( ( method_name .strapprox. "NORMAL" ) &
1439 .or. ( method_name .strapprox. "GRIDDED" ) &
1440 .or. ( method_name .strapprox. "STANDARD" ) ) then
1441
1442 this%init_precipitation_data => model_initialize_precip_normal
1443 this%get_precipitation_data => model_get_precip_normal
1444
1445 call logs%WRITE( "==> STANDARD PRECIPITATION submodel selected.", &
1446 iloglevel = log_all, lecho = false )
1447
1448 elseif ( ( method_name .strapprox. "TABLE") &
1449 .or. (method_name .strapprox. "TABULAR") ) then
1450
1451 this%init_precipitation_data => model_initialize_precip_tabular
1452 this%get_precipitation_data => model_get_precip_tabular
1453 this%get_maximum_air_temperature_data => model_get_maximum_air_temperature_tabular
1454 this%get_minimum_air_temperature_data => model_get_minimum_air_temperature_tabular
1455
1456 call logs%WRITE( "==> TABULAR PRECIPITATION submodel selected.", &
1457 iloglevel = log_all, lecho = false )
1458 call logs%WRITE( " PRECIPITATION, TMIN, and TMAX will be supplied as TABLE values.", &
1459 iloglevel = log_all, lecho = false )
1460
1461 elseif ( ( method_name .strapprox. "METHOD_OF_FRAGMENTS" ) &
1462 .or. ( method_name .strapprox. "FRAGMENTS" ) ) then
1463
1464 this%init_precipitation_data => model_initialize_precip_method_of_fragments
1465 this%get_precipitation_data => model_get_precip_method_of_fragments
1466
1467 call logs%WRITE( "==> METHOD OF FRAGMENTS PRECIPITATION submodel selected.", &
1468 iloglevel = log_all, lecho = false )
1469
1470 else
1471
1472 call warn("Your control file specifies an unknown or unsupported PRECIPITATION method.", &
1473 lfatal = true, iloglevel = log_all, lecho = true )
1474
1475 endif
1476
1477 elseif ( (scmdtext .containssimilar. "DIRECT_NET_INFILTRATION" ) &
1478 .or. ( scmdtext .containssimilar. "DIRECT_RECHARGE" ) ) then
1479
1480 this%init_direct_net_infiltration => model_initialize_direct_net_infiltration_gridded
1481 this%calc_direct_net_infiltration => model_calculate_direct_net_infiltration_gridded
1482
1483 call logs%WRITE( "==> GRIDDED or TABULAR values for water main leakage and other direct " &
1484 //"net infiltration will be used.", iloglevel = log_all, lecho = false )
1485
1486 elseif ( scmdtext .containssimilar. "DIRECT_SOIL_MOISTURE" ) then
1487
1488 this%init_direct_soil_moisture => model_initialize_direct_soil_moisture_gridded
1489 this%calc_direct_soil_moisture => model_calculate_direct_soil_moisture_gridded
1490
1491 call logs%WRITE( "==> GRIDDED or TABULAR values for septic drainage and other direct " &
1492 //"inputs to the root zone will be used.", iloglevel = log_all, lecho = false )
1493
1494 elseif ( scmdtext .containssimilar. "SOIL_MOISTURE" ) then
1495
1496 if ( ( method_name .strapprox. "T-M" ) &
1497 .or. ( method_name .strapprox. "THORNTHWAITE-MATHER" ) &
1498 .or. ( method_name .strapprox. "THORNTHWAITE_MATHER" ) &
1499 .or. ( method_name .strapprox. "THORNTHWAITE") ) then
1500
1503
1504 call logs%WRITE( "==> THORNTHWAITE-MATHER SOIL MOISTURE RETENTION submodel selected.", &
1505 iloglevel = log_all, lecho = false )
1506
1507 elseif ( ( method_name .strapprox. "T-M_EQUATIONS" ) &
1508 .or. ( method_name .strapprox. "THORNTHWAITE-MATHER_EQUATIONS" ) &
1509 .or. ( method_name .strapprox. "THORNTHWAITE_MATHER_EQUATIONS") ) then
1510
1511 ! alert! we are just pointing to the normal thornthwaite-mather relations
1514
1515 call warn(smessage="The SOIL_MOISTURE_METHOD 'THORNTHWAITE_MATHER_EQUATIONS' option has" &
1516 //" been removed.", &
1517 shints="Please select the normal 'THORNTHWAITE_MATHER' SOIL_MOISTURE_METHOD and " &
1518 //"try rerunning swb.", lfatal=true)
1519
1520
1521 elseif ( ( method_name .strapprox. "FAO56_TWO_STAGE" ) .or. ( method_name .strapprox. "FAO-56_TWO_STAGE" ) &
1522 .or. ( method_name .strapprox. "FAO-56_TWO-STAGE" )) then
1523
1524 this%init_actual_et => model_initialize_actual_et_fao56__two_stage
1525 this%calc_actual_et => model_calculate_actual_et_fao56__two_stage
1526
1527 call logs%WRITE( "==> **TWO-STAGE** FAO-56 SOIL MOISTURE RETENTION submodel selected.", &
1528 iloglevel = log_all, lecho = false )
1529
1530 elseif ( ( method_name .strapprox. "FAO56" ) .or. ( method_name .strapprox. "FAO-56" ) ) then
1531
1532 this%init_actual_et => model_initialize_actual_et_fao56
1533 this%calc_actual_et => model_calculate_actual_et_fao56
1534
1535 call logs%WRITE( "==> FAO-56 SOIL MOISTURE RETENTION submodel selected.", &
1536 iloglevel = log_all, lecho = false )
1537
1538 elseif ( ( method_name .strapprox. "GRIDDED" ) ) then
1539
1540 this%init_actual_et => model_initialize_actual_et_gridded_values
1541 this%calc_actual_et => model_calculate_actual_et_gridded_values
1542
1543 call logs%WRITE( "==> **GRIDDED** ACTUAL ET will determine SOIL MOISTURE RETENTION.", &
1544 iloglevel = log_all, lecho = false )
1545
1546 else
1547
1548 call warn("Your control file specifies an unknown or unsupported SOIL_MOISTURE method.", &
1549 lfatal = true, iloglevel = log_all, lecho = true )
1550
1551 endif
1552
1553 elseif ( scmdtext .containssimilar. "DUMP_VARIABLES" ) then
1554
1555 row = 0; col = 0; indx_start = 0; indx_end = 0
1556 xcoord=99999.; ycoord=99999.
1557 dump_file_prefix = ""
1558 modifier_text = ""
1559 temp_str = "__"
1560
1561 if ( ( method_name .containssimilar. "INDEX_RANGE") .and. ( argv_list%count >= 3 ) ) then
1562
1563 indx_start = asint( argv_list%get(2) )
1564 indx_end = asint( argv_list%get(3) )
1565
1566 elseif ( ( method_name .containssimilar. "COORDINATES") .and. ( argv_list%count >= 3 ) &
1567 .or. ( method_name .containssimilar. "COORD") .and. ( argv_list%count >= 3 ) ) then
1568
1569 xcoord = asfloat( argv_list%get(2) )
1570 ycoord = asfloat( argv_list%get(3) )
1571 row = grid_getgridrownum( this%pGrdOut, ycoord )
1572 col = grid_getgridcolnum( this%pGrdOut, xcoord )
1573
1574 elseif ( ( method_name .containssimilar. "COL_ROW") .and. ( argv_list%count >= 3 ) ) then
1575
1576 col = asint( argv_list%get(2) )
1577 row = asint( argv_list%get(3) )
1578 xcoord = grid_getgridx( this%pGrdOut, col )
1579 ycoord = grid_getgridy( this%pGrdOut, row )
1580
1581 else
1582
1583 call warn("Unknown option and/or arguments supplied to DUMP_VARIABLES method.", &
1584 shints="The known option keywords are 'COL_ROW', 'COORD(INATES)' and 'INDEX_RANGE'.", &
1585 lfatal = true, iloglevel = log_all, lecho = true )
1586
1587 endif
1588
1589 if ( argv_list%count == 5) then
1590 modifier_text = argv_list%get(4)
1591 if (modifier_text .containssimilar. "ID") then
1592 dump_file_prefix = argv_list%get(5)
1593 temp_str = "__"//trim(dump_file_prefix)//"__"
1594 else
1595 call warn("Unknown option modifier supplied to DUMP_VARIABLES method.", &
1596 shints="The known option modifier is 'ID. You supplied "//trim(modifier_text), &
1597 lfatal = true, iloglevel = log_all, lecho = true )
1598 endif
1599 endif
1600
1601 row_col_num_are_valid = grid_rowcolfallsinsidegrid( this%pGrdOut, row, col )
1602 coordinates_are_valid = grid_coordinatesfallinsidegrid( this%pGrdOut, xcoord, ycoord )
1603 indices_are_valid = ( (indx_start >= lbound(this%col_num_1D, 1) ) &
1604 .and. (indx_start <= ubound(this%col_num_1D, 1) ) &
1605 .and. (indx_end >= lbound(this%col_num_1D, 1) ) &
1606 .and. (indx_end <= ubound(this%col_num_1D, 1) ) )
1607
1608 if ( row_col_num_are_valid .or. indices_are_valid ) then
1609
1610 if ( allocated(dump) ) then
1611 allocate(temp_dump(size(dump,1)+1) )
1612 temp_dump(:size(dump,1)) = dump
1613 call move_alloc(temp_dump,dump)
1614 else
1615 allocate(dump(1))
1616 this%dump_variables => model_dump_variables_by_cell
1617 endif
1618
1619 do indx=1, ubound( dump, 1)
1620
1621 ! scan through list; if 'col' or 'indx_start' already have values, skip to the next,
1622 ! looking for an empty slot in which to store the dump variable coordinates and indices
1623 if (dump( indx )%col /= 0 .or. dump( indx )%indx_start /= 0 ) cycle
1624
1625 dump( indx )%col = col
1626 dump( indx )%row = row
1627 dump( indx )%indx_start = indx_start
1628 dump( indx )%indx_end = indx_end
1629 dump( indx )%x_coord = real(xcoord, c_float)
1630 dump( indx )%y_coord = real(ycoord, c_float)
1631
1632 if ( row_col_num_are_valid ) then
1633 call logs%WRITE( "==> SWB will dump variables for cell ("//ascharacter(col)//"," &
1634 //ascharacter(row)//").", iloglevel = log_all, lecho = false )
1635 filename = trim(output_directory_name)//"SWB2_variable_values" &
1636 //trim(temp_str)//"col_" &
1637 //ascharacter( col )//"__row_" &
1638 //ascharacter( row )//"__x_"//ascharacter(asint(xcoord)) &
1639 //"__y_"//ascharacter(asint(ycoord))//".csv"
1640
1641 elseif ( indices_are_valid ) then
1642 call logs%WRITE( "==> SWB will dump variables for cell indices ranging from " &
1643 //ascharacter(indx_start)//" to "//ascharacter(indx_end)//").", &
1644 iloglevel = log_all, lecho = false )
1645 filename = trim(output_directory_name)//"SWB2_variable_values" &
1646 //trim(temp_str)//"start_index_" &
1647 //ascharacter( indx_start )//"__end_index_"//ascharacter( indx_end )//".csv"
1648 endif
1649
1650 open( newunit=unitnum, file=trim(filename), iostat=iostat, action="write", status="replace" )
1651
1652 call assert( iostat == 0, "Could not open variable dump file "//squote(filename) &
1653 //" for writing. iostat = "//ascharacter( iostat ) )
1654 dump( indx )%unitnum = unitnum
1655
1656 write( unit=dump( indx )%unitnum, fmt="(a)") &
1657 "date, month, day, year,landuse_code, landuse_index, soil_group, num_upslope_connections, " &
1658 //"sum_upslope_cells, solution_order, cell_index, target_index, growing_season, " &
1659 //"awc, latitude, reference_ET0, " &
1660 //"actual_ET, curve_num_adj, gross_precip, inflow, runon, " &
1661 //"runoff, outflow, infiltration, snowfall, potential_snowmelt, snowmelt, interception, " &
1662 //"rainfall, net_rainfall, monthly_gross_precip, monthly_runoff, interception_storage, tmax, tmin, " &
1663 //" tmean, snow_storage, soil_storage, soil_storage_max, " &
1664 //"evaporable_water_storage, evaporable_water_deficit, delta_soil_storage, " &
1665 //"soil_moisture_deficit, surface_storage, " &
1666 //"surface_storage_excess, surface_storage_max, net_infiltration, " &
1667 //"rejected_net_infiltration, fog, irrigation, gdd, runoff_outside, " &
1668 //"pervious_fraction, storm_drain_capture, canopy_cover_fraction, crop_coefficient_kcb, " &
1669 //"cfgi, rooting_depth_max, current_rooting_depth, current_plant_height, actual_et_soil, " &
1670 //"readily_available_water, total_available_water, plant_stress_coef_ks, " &
1671 //"evap_reduction_coef_kr, surf_evap_coef_ke, fraction_exposed_and_wetted_soil, " &
1672 //"actual_et_impervious, actual_et_interception, adjusted_depletion_fraction_p, crop_etc, " &
1673 //" bare_soil_evap, direct_net_infiltration, " &
1674 //"direct_soil_moisture, inflowbuf1, inflowbuf2, inflowbuf3, inflowbuf4, inflowbuf5, inflowbuf_sum"
1675 exit
1676
1677 enddo
1678
1679 else
1680
1681 call warn("You are attempting to dump variables using invalid coordinates or index values.", &
1682 lfatal = false, iloglevel = log_all, lecho = true )
1683
1684 endif
1685
1686 else
1687
1688 call warn("Your control file references an unknown or unsupported method: "//dquote(scmdtext), &
1689 lfatal = true, iloglevel = log_all, lecho = true )
1690
1691 endif
1692
1693 end subroutine set_method_pointers_sub
1694
1695!--------------------------------------------------------------------------------------------------
1696
1698
1700
1701 class(model_domain_t), intent(inout) :: this
1702
1703 call interception_bucket_initialize( this%active )
1704
1706
1707!--------------------------------------------------------------------------------------------------
1708
1710
1714
1715 class(model_domain_t), intent(inout) :: this
1716
1717 where ( this%it_is_growing_season )
1718 this%interception_storage_max = bucket_interception_storage_max_growing_season( this%landuse_index )
1719 elsewhere
1720 this%interception_storage_max = bucket_interception_storage_max_nongrowing_season( this%landuse_index )
1721 end where
1722
1723 call interception_bucket_calculate( this%landuse_index, this%gross_precip, this%fog, &
1724 this%canopy_cover_fraction, this%it_is_growing_season, &
1725 this%interception )
1726
1728
1729!--------------------------------------------------------------------------------------------------
1730
1732
1734
1735 class(model_domain_t), intent(inout) :: this
1736
1737 call interception_gash_initialize( this%active, this%canopy_cover_fraction, this%landuse_index )
1738
1739 where ( this%it_is_growing_season )
1740 this%interception_storage_max = gash_interception_storage_max_growing_season( this%landuse_index )
1741 elsewhere
1742 this%interception_storage_max = gash_interception_storage_max_nongrowing_season( this%landuse_index )
1743 end where
1744
1746
1747!--------------------------------------------------------------------------------------------------
1748
1750
1752
1753 class(model_domain_t), intent(inout) :: this
1754
1755 ! [ LOCALS ]
1756 real (c_float), allocatable :: fTrunk_Storage_Capacity(:)
1757 real (c_float), allocatable :: fStemflow_Fraction(:)
1758
1759 ftrunk_storage_capacity = trunk_storage_capacity_table_values( this%landuse_index )
1760 fstemflow_fraction = stemflow_fraction_table_values( this%landuse_index )
1761
1762 call interception_gash_calculate( this%rainfall, &
1763 this%fog, &
1764 this%canopy_cover_fraction, &
1765 !TRUNK_STORAGE_CAPACITY_TABLE_VALUES( this%landuse_index ), &
1766 ftrunk_storage_capacity, &
1767 !STEMFLOW_FRACTION_TABLE_VALUES( this%landuse_index ), &
1768 fstemflow_fraction, &
1770 p_sat, &
1771 this%interception )
1772
1774
1775!--------------------------------------------------------------------------------------------------
1776
1778
1779 class(model_domain_t), intent(inout) :: this
1780
1781 this%runon = 0.0_c_float
1782
1783 end subroutine model_initialize_routing_none
1784
1785!--------------------------------------------------------------------------------------------------
1786
1787 subroutine model_calculate_routing_none(this, indx)
1788
1789 class(model_domain_t), intent(inout) :: this
1790 integer (c_int), intent(in) :: indx
1791
1792 this%runoff_outside( indx ) = &
1793 this%runoff( indx ) &
1794 + this%rejected_net_infiltration( indx )
1795
1796 end subroutine model_calculate_routing_none
1797
1798!--------------------------------------------------------------------------------------------------
1799
1801
1802 use routing__d8
1803
1804 class(model_domain_t), intent(inout) :: this
1805
1806 call routing_d8_initialize( this%active, this%sort_order )
1807 this%num_upslope_connections = pack( number_of_upslope_connections, this%active )
1808 this%sum_upslope_cells = pack( sum_of_upslope_cells, this%active )
1809
1810 end subroutine model_initialize_routing_d8
1811
1812!--------------------------------------------------------------------------------------------------
1813
1814 subroutine model_calculate_routing_d8( this, indx )
1815
1817
1818 class(model_domain_t), intent(inout) :: this
1819 integer (c_int), intent(in) :: indx
1820
1821 ! [ LOCALS ]
1822 integer (c_int) :: target_index
1823 integer (c_int) :: cell_index
1824
1825 integer (c_int) :: cell_row, cell_col, targ_row, targ_col
1826
1827 cell_index = get_cell_index( indx )
1828 target_index = get_target_index( indx )
1829
1830 cell_row=this%row_num_1D(cell_index)
1831 cell_col=this%col_num_1D(cell_index)
1832 targ_row=-9999
1833 targ_col=-9999
1834
1835 ! if the target cell is within valid bounds, move the water downslope
1836 if ( ( target_index >= lbound( this%runon, 1) ) &
1837 .and. ( target_index <= ubound( this%runon, 1) ) ) then
1838
1839 targ_row=this%row_num_1D(target_index)
1840 targ_col=this%col_num_1D(target_index)
1841
1842 this%runon( target_index ) = &
1843 this%runon( target_index ) &
1844 + this%runoff( cell_index ) &
1845 + this%rejected_net_infiltration( cell_index )
1846
1847 ! msb = this%rainfall( cell_index ) + this%snowmelt( cell_index ) + this%runon( cell_index ) &
1848 ! - this%runoff( cell_index ) + this%delta_soil_storage( cell_index ) &
1849 ! - this%net_infiltration( cell_index ) - this%actual_et( cell_index ) &
1850 ! - this%rejected_net_infiltration( cell_index )
1851 !
1852
1853 ! print *, " ("//asCharacter( cell_col )//","//asCharacter( cell_row )//")" &
1854 ! //" to ("//asCharacter( targ_col )//","//asCharacter( targ_row )//")"
1855 ! print *, " cell runon = ", this%runon( cell_index )
1856 ! print *, " cell rainfall = ", this%rainfall( cell_index )
1857 ! print *, " cell snowmelt = ", this%snowmelt( cell_index )
1858 ! print *, " cell fog = ", this%fog( cell_index )
1859 ! print *, " cell irrigation = ", this%irrigation( cell_index )
1860 ! print *, " surface storage excess = ", this%surface_storage_excess( cell_index )
1861 ! print *, " direct_soil_moisture = ", this%direct_soil_moisture( cell_index )
1862 ! print *, " cell infiltration =", this%infiltration( cell_index )
1863 ! print *, " cell runoff = ", this%runoff( cell_index )
1864 ! print *, " cell delta_soil_storage = ", this%delta_soil_storage( cell_index )
1865 ! print *, " cell act_et = ", this%actual_et( cell_index )
1866 ! print *, " cell net_infiltration =", this%net_infiltration( cell_index )
1867 ! print *, " cell rejected_net_infiltration =", this%rejected_net_infiltration( cell_index )
1868 ! print *, " target runon = ", this%runon( target_index )
1869 ! print *, " cell msb = ", msb
1870
1871 else
1872
1873 ! move the water out of grid
1874 this%runoff_outside( cell_index ) = &
1875 this%runoff_outside( cell_index ) &
1876 + this%runoff( cell_index ) &
1877 + this%rejected_net_infiltration( cell_index )
1878
1879 endif
1880
1881 end subroutine model_calculate_routing_d8
1882
1883!--------------------------------------------------------------------------------------------------
1884
1886
1888
1889 class(model_domain_t), intent(inout) :: this
1890
1891 call initialize_continuous_frozen_ground_index( this%continuous_frozen_ground_index, &
1892 this%cfgi_lower_limit, &
1893 this%cfgi_upper_limit, &
1894 this%active )
1895
1897
1898!--------------------------------------------------------------------------------------------------
1899
1901
1903
1904 class(model_domain_t), intent(inout) :: this
1905
1906 call update_continuous_frozen_ground_index( this%continuous_frozen_ground_index, this%tmin, &
1907 this%tmax, this%snow_storage )
1908
1910
1911!--------------------------------------------------------------------------------------------------
1912
1914
1915 class(model_domain_t), intent(inout) :: this
1916
1918
1919!--------------------------------------------------------------------------------------------------
1920
1922
1923 class(model_domain_t), intent(inout) :: this
1924
1925 call snowfall_original_calculate( this%snowfall, this%net_snowfall, &
1926 this%rainfall, this%net_rainfall, &
1927 this%tmin, this%tmax, &
1928 this%interception, this%gross_precip )
1929
1931
1932!--------------------------------------------------------------------------------------------------
1933
1935
1936 class(model_domain_t), intent(inout) :: this
1937
1938 end subroutine model_initialize_snowfall_prms
1939
1940!--------------------------------------------------------------------------------------------------
1941
1943
1944 class(model_domain_t), intent(inout) :: this
1945
1946 end subroutine model_calculate_snowfall_prms
1947
1948!--------------------------------------------------------------------------------------------------
1949
1951
1952 class(model_domain_t), intent(inout) :: this
1953
1955
1956!--------------------------------------------------------------------------------------------------
1957
1959
1961
1962 class(model_domain_t), intent(inout) :: this
1963
1964 call snowmelt_original_calculate( potential_snowmelt=this%potential_snowmelt, tmin=this%tmin, &
1965 tmax=this%tmax, imperial_units=true )
1966
1968
1969!--------------------------------------------------------------------------------------------------
1970
1972
1973 class(model_domain_t), intent(inout) :: this
1974
1975 end subroutine model_initialize_snowmelt_prms
1976
1977!--------------------------------------------------------------------------------------------------
1978
1980
1981 class(model_domain_t), intent(inout) :: this
1982
1983 end subroutine model_calculate_snowmelt_prms
1984
1985 !--------------------------------------------------------------------------------------------------
1986
1988
1990
1991 class(model_domain_t), intent(inout) :: this
1992
1994
1995 end subroutine model_initialize_et_hargreaves
1996
1997 !--------------------------------------------------------------------------------------------------
1998
2000
2002
2003 class(model_domain_t), intent(inout) :: this
2004
2005 this%reference_ET0 = et_hargreaves_calculate( idayofyear=sim_dt%iDOY, inumdaysinyear=sim_dt%iDaysInYear, &
2006 flatitude=this%latitude, ftmin=this%Tmin, ftmax=this%Tmax )
2007
2008 end subroutine model_calculate_et_hargreaves
2009
2010 !--------------------------------------------------------------------------------------------------
2011
2013
2015
2016 class(model_domain_t), intent(inout) :: this
2017
2018 call et_gridded_values_initialize( this%active )
2019
2020 end subroutine model_initialize_et_daily_grid
2021
2022 !--------------------------------------------------------------------------------------------------
2023
2025
2027
2028 class(model_domain_t), intent(inout) :: this
2029
2031
2032 this%reference_ET0 = pack( pet_grid%pGrdBase%rData, this%active )
2033
2034 end subroutine model_calculate_et_daily_grid
2035
2036 !--------------------------------------------------------------------------------------------------
2037
2039
2040 use et__zone_values
2041
2042 class(model_domain_t), intent(inout) :: this
2043
2044 call et_zone_values_initialize( this%active )
2045
2047
2048 !--------------------------------------------------------------------------------------------------
2049
2051
2052 use et__zone_values
2053
2054 class(model_domain_t), intent(inout) :: this
2055
2057
2058 ! as with HWB, multiply ANNUAL ET grid by a monthly to annual RATIO, then divide by number of days
2059 this%reference_ET0 = pack( pet_grid%pGrdBase%rData, this%active ) * et_ratios / real( sim_dt%iDaysInMonth, c_float)
2060
2062
2063 !--------------------------------------------------------------------------------------------------
2064
2066
2068
2069 class(model_domain_t), intent(inout) :: this
2070
2071 call et_gridded_values_initialize( this%active )
2072
2074
2075 !--------------------------------------------------------------------------------------------------
2076
2078
2080
2081 class(model_domain_t), intent(inout) :: this
2082
2084
2085 this%reference_ET0 = pack( pet_grid%pGrdBase%rData, this%active ) &
2086 / real( sim_dt%iDaysInMonth, c_float)
2087
2088 end subroutine model_calculate_et_monthly_grid
2089
2090!--------------------------------------------------------------------------------------------------
2091
2093
2095
2096 class(model_domain_t), intent(inout) :: this
2097
2099
2100!--------------------------------------------------------------------------------------------------
2101
2103
2105
2106 class(model_domain_t), intent(inout) :: this
2107
2108 this%reference_ET0 = et_jh_calculate( idayofyear=sim_dt%iDOY, inumdaysinyear=sim_dt%iDaysInYear, &
2109 flatitude=this%latitude, ftmin=this%Tmin, ftmax=this%Tmax )
2110
2111 end subroutine model_calculate_et_jensen_haise
2112
2113!--------------------------------------------------------------------------------------------------
2114
2116
2118
2119 class(model_domain_t), intent(inout) :: this
2120
2121 call runoff_curve_number_initialize( this%active )
2122
2124
2125!--------------------------------------------------------------------------------------------------
2126
2127 subroutine model_calculate_runoff_curve_number(this, cell_index )
2128
2129 use ieee_arithmetic, only : ieee_is_nan, ieee_is_finite
2132
2133 class(model_domain_t), intent(inout) :: this
2134 integer (c_int), intent(in) :: cell_index
2135
2136
2137 !> @TODO: Should interception term be part of this? Initial abstraction should include
2138 !! some of this interception...
2139
2140! call update_previous_5_day_rainfall( this%inflow( cell_index ), cell_index )
2141
2142 call runoff_curve_number_calculate(runoff=this%runoff( cell_index ), &
2143 curve_num_adj=this%curve_num_adj( cell_index ), &
2144 landuse_index=this%landuse_index( cell_index ), &
2145 cell_index=cell_index, &
2146 soil_group=this%soil_group( cell_index ), &
2147 soil_storage_max=this%soil_storage_max( cell_index ), &
2148 it_is_growing_season=this%it_is_growing_season( cell_index ), &
2149 inflow=this%inflow( cell_index ), &
2151 this%continuous_frozen_ground_index( cell_index ), &
2152 cfgi_lower_limit=this%cfgi_lower_limit(cell_index), &
2153 cfgi_upper_limit=this%cfgi_upper_limit( cell_index) )
2154
2155 call update_previous_5_day_rainfall( this%inflow( cell_index ), cell_index )
2156
2157 ! if ( ieee_is_nan( this%runoff( cell_index ) ) &
2158 ! .or. ( .not. ieee_is_finite( this%runoff( cell_index ) ) ) ) then
2159 !
2160 ! print *, "*** NaN or infinite runoff value detected ***"
2161 ! print *, " LU: ", this%landuse_code( cell_index )
2162 ! print *, " soil: ", this%soil_group( cell_index )
2163 ! print *, " col: ", this%col_num_1D( cell_index )
2164 ! print *, " row: ", this%row_num_1D( cell_index )
2165 ! print *, " runon: ", this%runon( cell_index )
2166 ! print *, " inflow: ", this%inflow( cell_index )
2167 ! print *, " soil_stor_max: ", this%soil_storage_max( cell_index )
2168 ! print *, " soil_stor: ", this%soil_storage( cell_index )
2169 ! print *, " curve_num_adj: ", this%curve_num_adj( cell_index )
2170 !
2171 ! endif
2172
2174
2175!--------------------------------------------------------------------------------------------------
2176
2178
2180
2181 class(model_domain_t), intent(inout) :: this
2182
2183 ! [ LOCALS ]
2184 integer (c_int) :: status
2185
2186 allocate( this%monthly_runoff( count( this%active ) ), stat=status)
2187 call assert( status==0, "Problem allocating memory", __file__, __line__ )
2188
2189 call runoff_gridded_values_initialize( this%active )
2191
2193
2194!--------------------------------------------------------------------------------------------------
2195
2197
2199 use datetime, only : datetime_t
2200
2201 class(model_domain_t), intent(inout) :: this
2202 integer (c_int), intent(in) :: indx
2203
2204 ! [ LOCALS ]
2205 type (DATETIME_T), save :: date_of_last_grid_update
2206 real (c_float) :: interim_inflow
2207
2208 if ( .not. ( date_of_last_grid_update == sim_dt%curr ) ) then
2210 date_of_last_grid_update = sim_dt%curr
2211 endif
2212
2213 interim_inflow = this%rainfall( indx ) + this%snowmelt( indx )
2214
2215 this%runoff( indx ) = interim_inflow * runoff_ratios( indx )
2216
2217 if ( allocated( this%monthly_gross_precip ) ) &
2218 this%monthly_runoff( indx ) = this%monthly_gross_precip( indx ) * runoff_ratios( indx )
2219
2221
2222!--------------------------------------------------------------------------------------------------
2223
2225
2226 class(model_domain_t), intent(inout) :: this
2227
2228 ! [ LOCALS ]
2229 integer (c_int) :: iNumActiveCells
2230 integer (c_int) :: iStat
2231 integer (c_int) :: iNumberOfLanduses
2232 integer (c_int) :: iNumberOfSoilGroups
2233 integer (c_int) :: iSoilsIndex
2234 integer (c_int) :: iLUIndex
2235 integer (c_int), allocatable :: iLanduseCodes(:)
2236 type (FSTRING_LIST_T) :: slList
2237 type (FSTRING_LIST_T) :: slRZ
2238 integer (c_int), allocatable :: iRZ_SeqNums(:)
2239 real (c_float), allocatable :: RZ(:)
2240 character (len=:), allocatable :: sText
2241 type (GENERAL_GRID_T), pointer :: pRooting_Depth
2242 real (c_float), allocatable :: fMax_Rooting_Depth(:,:)
2243 character (len=10) :: date_str
2244
2245 type (DATA_CATALOG_ENTRY_T), pointer :: pHSG
2246 type (DATA_CATALOG_ENTRY_T), pointer :: pLULC
2247
2248 plulc => dat%find("LAND_USE")
2249 phsg => dat%find("HYDROLOGIC_SOILS_GROUP")
2250
2251 date_str = sim_dt%curr%prettydate()
2252
2253 call assert( associated( plulc), "Possible INTERNAL PROGRAMMING ERROR -- Null pointer detected for pLULC", &
2254 __file__, __line__ )
2255
2256 call assert( associated( plulc%pGrdBase ), &
2257 "Possible INTERNAL PROGRAMMING ERROR -- Null pointer detected for pLULC%pGrdBase", __file__, __line__ )
2258
2259 call assert( allocated( plulc%pGrdBase%iData ), &
2260 "Possible INTERNAL PROGRAMMING ERROR -- Unallocated array detected for pLULC%pGrdBase%iData", __file__, __line__ )
2261
2262 call assert( associated( phsg), "Possible INTERNAL PROGRAMMING ERROR -- Null pointer detected for pHSG", &
2263 __file__, __line__ )
2264
2265 call assert( associated( phsg%pGrdBase ), &
2266 "Possible INTERNAL PROGRAMMING ERROR -- Null pointer detected for pHSG%pGrdBase", __file__, __line__ )
2267
2268 call assert( allocated( phsg%pGrdBase%iData ), &
2269 "Possible INTERNAL PROGRAMMING ERROR -- Unallocated array detected for pHSG%pGrdBase%iData", __file__, __line__ )
2270
2271
2272 prooting_depth => grid_create( inx=this%number_of_columns, iny=this%number_of_rows, &
2273 rx0=this%X_ll, ry0=this%Y_ll, &
2274 rgridcellsize=this%gridcellsize, idatatype=grid_datatype_real )
2275
2276 inumactivecells = ubound(this%soil_storage_max,1)
2277
2278 call sllist%append("LU_Code")
2279 call sllist%append("Landuse_Code")
2280 call sllist%append("Landuse_Lookup_Code")
2281
2282 !> Determine how many soil groups are present
2283
2284 ! retrieve a string list of all keys associated with root zone depth (i.e. RZ_1, RZ_2, RZ_3, etc.)
2285 slrz = params%grep_name("RZ", lfatal=true )
2286 ! Convert the string list to an vector of integers; MODEL call strips off the "RZ_" part of label
2287 irz_seqnums = slrz%get_integer()
2288
2289 ! count how many items are present in the vector; MODEL should equal the number of soils groups
2290 inumberofsoilgroups = count( irz_seqnums > 0 )
2291
2292 !> Determine how many landuse codes are present; FATAL error if no landuse codes found
2293 call params%get_parameters( slkeys=sllist, ivalues=ilandusecodes, lfatal=true )
2294 inumberoflanduses = count( ilandusecodes >= 0 )
2295
2296 allocate( fmax_rooting_depth(inumberoflanduses, inumberofsoilgroups), stat=istat )
2297 call assert( istat == 0, "Failed to allocate memory for maximum rooting depth table", &
2298 __file__, __line__)
2299
2300 ! we should have the max rooting depth table fully filled out following MODEL block
2301 do isoilsindex = 1, inumberofsoilgroups
2302 stext = "RZ_"//ascharacter(isoilsindex)
2303 call params%get_parameters( skey=stext, fvalues=rz )
2304 fmax_rooting_depth(:, isoilsindex) = rz
2305 enddo
2306
2307 call logs%WRITE( "Landuse Code | Soils Code | Number of Matches | Rooting Depth (ft)", &
2308 iloglevel = log_debug, lecho = false )
2309 call logs%WRITE( "-------------|--------------|-------------------|------------------ ", &
2310 iloglevel = log_debug, lecho = false )
2311
2312 do isoilsindex = 1, inumberofsoilgroups
2313 do iluindex = 1, inumberoflanduses
2314
2315 call logs%WRITE( ascharacter(ilandusecodes( iluindex) )//" | "//ascharacter(isoilsindex)//" | "// &
2316 ascharacter(count( plulc%pGrdBase%iData == ilandusecodes( iluindex) &
2317 .and. phsg%pGrdBase%iData == isoilsindex ) )//" | " &
2318 //ascharacter( fmax_rooting_depth( iluindex, isoilsindex) ), &
2319 iloglevel = log_debug, lecho = false )
2320
2321
2322 where ( plulc%pGrdBase%iData == ilandusecodes( iluindex) .and. phsg%pGrdBase%iData == isoilsindex )
2323
2324 prooting_depth%rData = fmax_rooting_depth( iluindex, isoilsindex )
2325
2326 endwhere
2327
2328 enddo
2329
2330 enddo
2331
2332 call sllist%clear()
2333
2334 date_str = sim_dt%curr%prettydate()
2335
2336 call grid_writearcgrid("Maximum_rooting_depth__as_assembled_from_table__" &
2337 //trim(date_str)//".asc", prooting_depth )
2338
2339 rooting_depth_max = prooting_depth%rData
2340
2341 call grid_destroy( prooting_depth )
2342
2344
2345!--------------------------------------------------------------------------------------------------
2346
2348
2349 class(model_domain_t), intent(inout) :: this
2350
2351 ! [ LOCALS ]
2352 type ( GENERAL_GRID_T ), pointer :: pTempGrd
2353 character (len=10) :: date_str
2354
2355 !> @todo this should be in its own routine...
2356 this%current_rooting_depth = pack( rooting_depth_max, model%active )
2357 this%rooting_depth_max = pack( rooting_depth_max, model%active )
2358
2359 this%soil_storage_max = this%rooting_depth_max * this%awc
2360
2361 ptempgrd => grid_create( inx=this%number_of_columns, iny=this%number_of_rows, &
2362 rx0=this%X_ll, ry0=this%Y_ll, &
2363 rgridcellsize=this%gridcellsize, idatatype=grid_datatype_real )
2364
2365 ptempgrd%rData = unpack( this%soil_storage_max, this%active, this%nodata_fill_value )
2366
2367 date_str = sim_dt%curr%prettydate()
2368
2369 call grid_writearcgrid( sfilename="Soil_Storage_Maximum__as_calculated_inches__" &
2370 //trim(date_str)//".asc", pgrd=ptempgrd )
2371
2372 call grid_destroy( ptempgrd )
2373
2375
2376!--------------------------------------------------------------------------------------------------
2377
2379
2380 class(model_domain_t), intent(inout) :: this
2381
2382 ! [ LOCALS ]
2383 type ( GENERAL_GRID_T ), pointer :: pTempGrd
2384 type (DATA_CATALOG_ENTRY_T), pointer :: pSOIL_STORAGE_MAX_GRID
2385
2386 psoil_storage_max_grid => null()
2387
2388 ptempgrd => grid_create( inx=this%number_of_columns, iny=this%number_of_rows, &
2389 rx0=this%X_ll, ry0=this%Y_ll, &
2390 rgridcellsize=this%gridcellsize, idatatype=grid_datatype_real )
2391
2392 ! locate the data structure associated with the gridded rainfall zone entries
2393 psoil_storage_max_grid => dat%find("SOIL_STORAGE_MAX")
2394 if ( .not. associated(psoil_storage_max_grid) ) &
2395 psoil_storage_max_grid => dat%find("PLANT_AVAILABLE_WATER")
2396
2397 if ( .not. associated(psoil_storage_max_grid) ) &
2398 call die("A SOIL_STORAGE_MAX or PLANT_AVAILABLE_WATER grid must be supplied in order" &
2399 //" to make use of this option.", __file__, __line__ )
2400
2401 call psoil_storage_max_grid%getvalues( )
2402
2403 this%soil_storage_max = pack( psoil_storage_max_grid%pGrdBase%rData, this%active )
2404
2405 ptempgrd%rData = unpack( this%soil_storage_max, this%active, this%nodata_fill_value )
2406
2407 ! back-calculate awc to make it consistent with rooting_depth_max and given
2408 ! soil_storage_max gridded values
2409
2410 where ( .not. ( this%rooting_depth_max .approxequal. 0.0_c_float ) )
2411
2412 this%awc = this%soil_storage_max / this%rooting_depth_max
2413
2414 else where
2415
2416 this%awc = 0.0_c_float
2417
2418 end where
2419
2420 this%current_rooting_depth = this%rooting_depth_max
2421
2422 call grid_writearcgrid( sfilename="Maximum_Soil_Storage__as_read_in_inches.asc", pgrd=ptempgrd )
2423
2424 ptempgrd%rData = unpack( this%rooting_depth_max, this%active, this%nodata_fill_value )
2425
2426 call grid_writearcgrid( sfilename="Available_water_content__as_RECALCULATED_in_inches_per_foot.asc", pgrd=ptempgrd )
2427
2428 call grid_destroy( ptempgrd )
2429
2431
2432!--------------------------------------------------------------------------------------------------
2433
2435
2436 class(model_domain_t), intent(inout) :: this
2437
2438 this%irrigation = 0.0_c_float
2439
2441
2442!--------------------------------------------------------------------------------------------------
2443
2444 subroutine model_calculate_irrigation_none( this, indx )
2445
2446 class(model_domain_t), intent(inout) :: this
2447 integer (c_int), intent(in) :: indx
2448 !> Nothing here to see.
2449
2450 end subroutine model_calculate_irrigation_none
2451
2452!--------------------------------------------------------------------------------------------------
2453
2455
2456 class(model_domain_t), intent(inout) :: this
2457 !> Nothing here to see.
2458
2459 end subroutine model_output_irrigation_none
2460
2461!--------------------------------------------------------------------------------------------------
2462
2464
2465 use irrigation
2466
2467 class(model_domain_t), intent(inout) :: this
2468
2469 call irrigation__initialize( this%active )
2470
2471 end subroutine model_initialize_irrigation
2472
2473!--------------------------------------------------------------------------------------------------
2474
2475 subroutine model_calculate_irrigation( this, indx )
2476
2477 use irrigation
2478
2479 class(model_domain_t), intent(inout) :: this
2480 integer (c_int), intent(in) :: indx
2481
2482 ! [ LOCALS ]
2483
2484 ! if ( present(indx) ) then
2485
2486 if ( allocated( this%monthly_gross_precip ) .and. allocated( this%monthly_runoff ) ) then
2487
2488 call irrigation__calculate( irrigation_amount=this%irrigation(indx), &
2489 landuse_index=this%landuse_index(indx), &
2490 soil_storage=this%soil_storage(indx), &
2491 soil_storage_max=this%soil_storage_max(indx), &
2492 total_available_water=this%total_available_water_taw(indx), &
2493 rainfall=this%rainfall(indx), &
2494 runoff=this%runoff(indx), &
2495 crop_etc=this%crop_etc(indx), &
2496 irrigation_mask=this%irrigation_mask(indx), &
2497 num_days_since_planting=this%number_of_days_since_planting(indx), &
2498 monthly_rainfall=this%monthly_gross_precip(indx), &
2499 monthly_runoff=this%monthly_runoff(indx) )
2500
2501 else
2502
2503 call irrigation__calculate( irrigation_amount=this%irrigation(indx), &
2504 landuse_index=this%landuse_index(indx), &
2505 soil_storage=this%soil_storage(indx), &
2506 soil_storage_max=this%soil_storage_max(indx), &
2507 total_available_water=this%total_available_water_taw(indx), &
2508 rainfall=this%rainfall(indx), &
2509 runoff=this%runoff(indx), &
2510 crop_etc=this%crop_etc(indx), &
2511 irrigation_mask=this%irrigation_mask(indx), &
2512 num_days_since_planting=this%number_of_days_since_planting(indx) )
2513
2514 endif
2515
2516 ! else
2517 !
2518 ! if ( allocated( this%monthly_gross_precip ) .and. allocated( this%monthly_runoff ) ) then
2519 !
2520 ! call irrigation__calculate( irrigation_amount=this%irrigation, &
2521 ! landuse_index=this%landuse_index, &
2522 ! soil_storage=this%soil_storage, &
2523 ! soil_storage_max=this%soil_storage_max, &
2524 ! total_available_water=this%total_available_water_taw, &
2525 ! rainfall=this%rainfall, &
2526 ! runoff=this%runoff, &
2527 ! crop_etc=this%crop_etc, &
2528 ! irrigation_mask=this%irrigation_mask, &
2529 ! num_days_since_planting=this%number_of_days_since_planting, &
2530 ! monthly_rainfall=this%monthly_gross_precip, &
2531 ! monthly_runoff=this%monthly_runoff )
2532 !
2533 ! else
2534 !
2535 ! call irrigation__calculate( irrigation_amount=this%irrigation, &
2536 ! landuse_index=this%landuse_index, &
2537 ! soil_storage=this%soil_storage, &
2538 ! soil_storage_max=this%soil_storage_max, &
2539 ! total_available_water=this%total_available_water_taw, &
2540 ! rainfall=this%rainfall, &
2541 ! runoff=this%runoff, &
2542 ! crop_etc=this%crop_etc, &
2543 ! irrigation_mask=this%irrigation_mask, &
2544 ! num_days_since_planting=this%number_of_days_since_planting )
2545 !
2546 ! endif
2547 !
2548 ! endif
2549
2550 end subroutine model_calculate_irrigation
2551
2552!--------------------------------------------------------------------------------------------------
2553
2555
2556 class(model_domain_t), intent(inout) :: this
2557
2559
2560 !--------------------------------------------------------------------------------------------------
2561
2563
2565
2566 class(model_domain_t), intent(inout) :: this
2567
2569 landuse_index=this%landuse_index, &
2570 kcb=this%crop_coefficient_kcb, &
2571 it_is_growing_season=this%it_is_growing_season )
2572
2574
2575!--------------------------------------------------------------------------------------------------
2576
2578
2579 use growing_season
2580
2581 class(model_domain_t), intent(inout) :: this
2582
2584
2585 end subroutine model_initialize_growing_season
2586
2587!--------------------------------------------------------------------------------------------------
2588
2590
2591 use growing_season
2592
2593 class(model_domain_t), intent(inout) :: this
2594
2595 call growing_season_update( landuse_index=this%landuse_index, &
2596 gdd=this%gdd, &
2597 mean_air_temp=this%tmean, &
2598 it_is_growing_season=this%it_is_growing_season )
2599
2600 end subroutine model_update_growing_season
2601
2602!--------------------------------------------------------------------------------------------------
2603
2605
2607
2608 class(model_domain_t), intent(inout) :: this
2609
2611
2613
2614!--------------------------------------------------------------------------------------------------
2615
2617
2619
2620 class(model_domain_t), intent(inout) :: this
2621
2622 ! [ LOCALS ]
2623 type (GENERAL_GRID_T), pointer :: pTempGrd
2624
2625 ptempgrd => grid_create( inx=this%number_of_columns, iny=this%number_of_rows, &
2626 rx0=this%X_ll, ry0=this%Y_ll, &
2627 rgridcellsize=this%gridcellsize, idatatype=grid_datatype_real )
2628
2629 call awc_gridded_values_initialize( lactive=this%active, &
2630 fawc=this%awc )
2631
2632 ptempgrd%rData = unpack( this%awc, this%active, this%nodata_fill_value )
2633
2634 call grid_writearcgrid( sfilename="Available_water_content__as_read_in_inches_per_foot.asc", pgrd=ptempgrd )
2635
2636 call grid_destroy( ptempgrd )
2637
2638
2640
2641!--------------------------------------------------------------------------------------------------
2642
2644
2646
2647 class(model_domain_t), intent(inout) :: this
2648
2649 call awc_depth_integrated_read( frooting_depth=rooting_depth_max )
2650
2652
2653!--------------------------------------------------------------------------------------------------
2654
2656
2658
2659 class(model_domain_t), intent(inout) :: this
2660
2661 ! [ LOCALS ]
2662 integer (c_int) :: iStat
2663 type (GENERAL_GRID_T), pointer :: pTempGrd
2664
2665 ptempgrd => grid_create( inx=this%number_of_columns, iny=this%number_of_rows, &
2666 rx0=this%X_ll, ry0=this%Y_ll, &
2667 rgridcellsize=this%gridcellsize, idatatype=grid_datatype_real )
2668
2669
2670 allocate ( this%soil_code (count( this%active ) ), stat=istat )
2671
2672 call awc_depth_integrated_initialize( lactive=this%active, &
2673 fawc=this%awc, &
2674 isoils_code=this%soil_code )
2675
2676 ptempgrd%rData = unpack( this%awc, this%active, this%nodata_fill_value )
2677
2678 call grid_writearcgrid( sfilename="Available_water_content__as_calculated_inches_per_foot.asc", pgrd=ptempgrd )
2679
2680 call grid_destroy( ptempgrd )
2681
2683
2684!--------------------------------------------------------------------------------------------------
2685
2687
2688 class(model_domain_t), intent(inout) :: this
2689
2690 ! [ LOCALS ]
2691 type (DATA_CATALOG_ENTRY_T), pointer :: pIRR_MASK
2692 character (len=10) :: date_str
2693
2694 pirr_mask => dat%find("IRRIGATION_MASK")
2695
2696 if ( associated(pirr_mask) ) then
2697
2698 if (pirr_mask%iSourceDataForm == dynamic_grid) then
2699
2700 call pirr_mask%getvalues( sim_dt%curr )
2701
2702 if ( pirr_mask%lGridHasChanged ) then
2703 date_str = sim_dt%curr%prettydate()
2704 call grid_writearcgrid("Irrigation_mask__as_read_into_SWB__" &
2705 //trim(date_str)//".asc", pirr_mask%pGrdBase )
2706 this%irrigation_mask = pack( real(pirr_mask%pGrdBase%iData, c_float), this%active )
2707
2708 endif
2709
2710 else ! static grid; read in once at beginning of simulation
2711
2712 if (sim_dt%iDayOfSimulation < 1) then
2713 call pirr_mask%getvalues()
2714 this%irrigation_mask = pack( real(pirr_mask%pGrdBase%iData, c_float), this%active )
2715 call grid_writearcgrid("Irrigation_mask__as_read_into_SWB.asc", pirr_mask%pGrdBase )
2716 endif
2717
2718 endif
2719
2720 if ( any(real(pirr_mask%pGrdBase%iData, c_float) < 0.0) &
2721 .or. any(real(pirr_mask%pGrdBase%iData, c_float) > 1.0)) then
2722
2723 call die(smessage = "Irrigation mask contains illegal values (outside range from 0-1)", &
2724 shints="Check the values contained in your irrigation mask file(s).")
2725
2726 endif
2727
2728 else ! no irrigation mask specified; default to irrigating every cell
2729
2730 this%irrigation_mask = 1.0_c_float
2731
2732 endif
2733
2734 end subroutine model_update_irrigation_mask
2735
2736 !--------------------------------------------------------------------------------------------------
2737
2739
2740 class(model_domain_t), intent(inout) :: this
2741 !> Nothing here to see.
2742
2744
2745!--------------------------------------------------------------------------------------------------
2746
2748
2749 class(model_domain_t), intent(inout) :: this
2750 ! [ LOCALS ]
2751 type (DATA_CATALOG_ENTRY_T), pointer :: pLULC
2752
2753 plulc => dat%find("LAND_USE")
2754
2755 if ( associated(plulc) ) then
2756
2757 call read_landuse_codes()
2758
2759 if ( plulc%lGridHasChanged ) then
2761
2762 ! update the rooting depths by landuse and hydrologic soil group
2763 call this%update_rooting_depth_table()
2764 call this%init_soil_storage_max()
2765
2766 endif
2767
2768 endif
2769
2771
2772!--------------------------------------------------------------------------------------------------
2773
2774 subroutine model_initialize_gdd_none( this )
2775
2776 class(model_domain_t), intent(inout) :: this
2777 !> Nothing here to see.
2778
2779 end subroutine model_initialize_gdd_none
2780
2781!--------------------------------------------------------------------------------------------------
2782
2783 subroutine model_calculate_gdd_none( this )
2784
2785 class(model_domain_t), intent(inout) :: this
2786 !> Nothing here to see.
2787
2788 end subroutine model_calculate_gdd_none
2789
2790!--------------------------------------------------------------------------------------------------
2791
2792 subroutine model_initialize_gdd( this )
2793
2795
2796 class(model_domain_t), intent(inout) :: this
2797
2798 ! [ LOCALS ]
2799 integer (c_int) :: status
2800
2801 allocate( this%gdd( count( this%active ) ), stat=status )
2802 call assert( status==0, "Problem allocating memory.", __file__, __line__ )
2803
2804 this%gdd = 0.0_c_float
2805
2806 call growing_degree_day_initialize( is_cell_active=this%active, &
2807 landuse_index=this%landuse_index )
2808
2809 end subroutine model_initialize_gdd
2810
2811!--------------------------------------------------------------------------------------------------
2812
2813 subroutine model_calculate_gdd( this )
2814
2816
2817 class(model_domain_t), intent(inout) :: this
2818
2819 call growing_degree_day_calculate( gdd=this%gdd, &
2820 tmean=this%tmean, &
2821 order=this%sort_order )
2822
2823 end subroutine model_calculate_gdd
2824
2825!--------------------------------------------------------------------------------------------------
2826
2828
2830
2831 class(model_domain_t), intent(inout) :: this
2832
2833 call modified_growing_degree_day_calculate( gdd=this%gdd, &
2834 tmin=this%tmin, &
2835 tmax=this%tmax, &
2836 order=this%sort_order )
2837
2838 end subroutine model_calculate_modified_gdd
2839
2840!--------------------------------------------------------------------------------------------------
2841
2842 subroutine model_initialize_gdd_be( this )
2843
2845
2846 class(model_domain_t), intent(inout) :: this
2847
2848 ! [ LOCALS ]
2849 integer (c_int) :: status
2850
2851 allocate( this%gdd( count( this%active ) ), stat=status )
2852 call assert( status==0, "Problem allocating memory.", __file__, __line__ )
2853
2854 this%gdd = 0.0_c_float
2855
2856 call growing_degree_day_be_initialize( is_cell_active=this%active, &
2857 landuse_index=this%landuse_index )
2858
2859 end subroutine model_initialize_gdd_be
2860
2861 !--------------------------------------------------------------------------------------------------
2862
2863 subroutine model_calculate_gdd_be( this )
2864
2866
2867 class(model_domain_t), intent(inout) :: this
2868
2869 call growing_degree_day_be_calculate( gdd=this%gdd, &
2870 tmean=this%tmean, &
2871 tmin=this%tmin, &
2872 tmax=this%tmax, &
2873 order=this%sort_order )
2874
2875 end subroutine model_calculate_gdd_be
2876
2877!--------------------------------------------------------------------------------------------------
2878
2879 subroutine model_dump_variables_none( this )
2880
2881 class(model_domain_t), intent(inout) :: this
2882 !> Nothing here to see.
2883
2884 end subroutine model_dump_variables_none
2885
2886!--------------------------------------------------------------------------------------------------
2887
2889
2890 use routing__d8, only : get_sort_order
2891
2892 class(model_domain_t), intent(inout) :: this
2893
2894 ! [ LOCALS ]
2895 integer (c_int) :: jndx, indx_start, indx_end
2896
2897 ! iterating over the list of cells or cell ranges to dump
2898 do jndx=lbound( dump, 1), ubound( dump, 1)
2899
2900 indx_start = dump( jndx )%indx_start
2901 indx_end = dump( jndx )%indx_end
2902
2903 if ( (indx_start >= lbound( this%landuse_code, 1) ) &
2904 .and. ( indx_start <= ubound( this%landuse_code, 1) ) &
2905 .and. (indx_end >= lbound( this%landuse_code, 1) ) &
2906 .and. (indx_end <= ubound( this%landuse_code, 1) ) ) then
2907
2908 call model_dump_variables( this=this, unitnum=dump( jndx )%unitnum, &
2909 indx_start=indx_start, indx_end=indx_end )
2910
2911 else
2912
2913 ! this call returns the cell_index value
2914 indx_start = this%row_column_to_index( col_num=dump( jndx )%col, row_num=dump( jndx )%row)
2915
2916 ! the 'dump' subroutine expects to be gived the sort_order, not the actual
2917 ! cell_index
2918 indx_start = get_sort_order( indx_start )
2919
2920 if ( (indx_start >= lbound( this%landuse_code, 1) ) &
2921 .and. ( indx_start <= ubound( this%landuse_code, 1) ) ) &
2922
2923 call model_dump_variables( this=this, unitnum=dump( jndx )%unitnum, indx_start=indx_start )
2924
2925 endif
2926
2927 enddo
2928
2929 end subroutine model_dump_variables_by_cell
2930
2931!--------------------------------------------------------------------------------------------------
2932
2933! subroutine model_dump_variables_by_row( this )
2934
2935! class (MODEL_DOMAIN_T), intent(inout) :: this
2936
2937! ! [ LOCALS ]
2938! integer (c_int) :: indx, jndx
2939
2940! do jndx=lbound( DUMP, 1), ubound( DUMP, 1)
2941
2942! indx = this%row_column_to_index( col_num=DUMP( jndx )%col, row_num=DUMP( jndx )%row)
2943
2944! if ( (indx > lbound( this%landuse_code, 1) ) .and. ( indx <= ubound( this%landuse_code, 1) ) ) then
2945
2946! call model_dump_variables( this=this, unitnum=DUMP( jndx )%unitnum, indx=indx )
2947
2948! endif
2949
2950! enddo
2951
2952! end subroutine model_dump_variables_by_cell
2953
2954!--------------------------------------------------------------------------------------------------
2955
2956 subroutine model_dump_variables( this, unitnum, indx_start, indx_end )
2957
2960
2961 class(model_domain_t), intent(inout) :: this
2962 integer (c_int), intent(in) :: unitnum
2963 integer (c_int), intent(in) :: indx_start
2964 integer (c_int), intent(in), optional :: indx_end
2965
2966 ! [ LOCALS ]
2967 integer (c_int) :: kndx
2968 integer (c_int) :: target_indx
2969 integer (c_int) :: cell_indx
2970 integer (c_int) :: indx_end_l
2971 integer (c_int) :: indx
2972
2973 real (c_float) :: previous_5_day_rain(6)
2974 real (c_float) :: monthly_runoff
2975 real (c_float) :: monthly_gross_precip
2976
2977 previous_5_day_rain = -9999.0
2978 monthly_runoff = -9999.0
2979 monthly_gross_precip = -9999.0
2980
2981 if ( present( indx_end ) ) then
2982 indx_end_l = indx_end
2983 else
2984 indx_end_l = indx_start
2985 endif
2986
2987 do indx=indx_start, indx_end_l
2988 target_indx = get_target_index( indx )
2989 cell_indx = get_cell_index( indx )
2990
2991 if (allocated(prev_5_days_rain) ) previous_5_day_rain = prev_5_days_rain(cell_indx,:)
2992 if (allocated(this%monthly_runoff) ) monthly_runoff = this%monthly_runoff( cell_indx )
2993 if (allocated(this%monthly_gross_precip) ) monthly_gross_precip = this%monthly_gross_precip( cell_indx )
2994
2995 write( unit=unitnum, fmt="(i4,'-',i2.2,'-',i2.2,',',i2,',',i2,',',i4,',',9(i6,','),66(g20.12,','),g20.12)") &
2996 sim_dt%curr%iYear, sim_dt%curr%iMonth, sim_dt%curr%iDay, &
2997 sim_dt%curr%iMonth, sim_dt%curr%iDay, sim_dt%curr%iYear, &
2998 this%landuse_code( cell_indx ), &
2999 this%landuse_index( cell_indx ), &
3000 this%soil_group( cell_indx ), &
3001 this%num_upslope_connections( cell_indx ), &
3002 this%sum_upslope_cells( cell_indx ), &
3003 indx, &
3004 cell_indx, &
3005 target_indx, &
3006 asint(this%it_is_growing_season( cell_indx )), &
3007 this%awc( cell_indx ), &
3008 this%latitude( cell_indx ), &
3009 this%reference_ET0( cell_indx ), &
3010 this%actual_ET( cell_indx ), &
3011 this%curve_num_adj( cell_indx ), &
3012 this%gross_precip( cell_indx ), &
3013 this%inflow( cell_indx ), &
3014 this%runon( cell_indx ), &
3015 this%runoff( cell_indx ), &
3016 this%outflow( cell_indx ), &
3017 this%infiltration( cell_indx ), &
3018 this%snowfall( cell_indx ), &
3019 this%potential_snowmelt( cell_indx ), &
3020 this%snowmelt( cell_indx ), &
3021 this%interception( cell_indx ), &
3022 this%rainfall( cell_indx ), &
3023 this%net_rainfall( cell_indx ), &
3024 monthly_gross_precip, &
3025 monthly_runoff, &
3026 this%interception_storage( cell_indx ), &
3027 this%tmax( cell_indx ), &
3028 this%tmin( cell_indx ), &
3029 this%tmean( cell_indx ), &
3030 this%snow_storage( cell_indx ), &
3031 this%soil_storage( cell_indx ), &
3032 this%soil_storage_max( cell_indx ), &
3033 this%evaporable_water_storage( cell_indx ), &
3034 this%evaporable_water_deficit( cell_indx ), &
3035 this%delta_soil_storage( cell_indx ), &
3036 this%soil_moisture_deficit( cell_indx ), &
3037 this%surface_storage( cell_indx ), &
3038 this%surface_storage_excess( cell_indx ), &
3039 this%surface_storage_max( cell_indx ), &
3040 this%net_infiltration( cell_indx ), &
3041 this%rejected_net_infiltration( cell_indx ), &
3042 this%fog( cell_indx ), &
3043 this%irrigation( cell_indx ), &
3044 this%gdd( cell_indx ), &
3045 this%runoff_outside( cell_indx ), &
3046 this%pervious_fraction( cell_indx ), &
3047 this%storm_drain_capture( cell_indx ), &
3048 this%canopy_cover_fraction( cell_indx ), &
3049 this%crop_coefficient_kcb( cell_indx ), &
3050 this%continuous_frozen_ground_index( cell_indx ), &
3051 this%rooting_depth_max( cell_indx ), &
3052 this%current_rooting_depth( cell_indx ), &
3053 this%current_plant_height( cell_indx), &
3054 this%actual_et_soil( cell_indx ), &
3055 this%readily_available_water_raw( cell_indx ), &
3056 this%total_available_water_taw( cell_indx ), &
3057 this%plant_stress_coef_ks( cell_indx ), &
3058 this%evap_reduction_coef_kr( cell_indx ), &
3059 this%surf_evap_coef_ke( cell_indx ), &
3060 this%fraction_exposed_and_wetted_soil( cell_indx ), &
3061 this%actual_et_impervious( cell_indx ), &
3062 this%actual_et_interception( cell_indx ), &
3063 this%adjusted_depletion_fraction_p( cell_indx ), &
3064 this%crop_etc( cell_indx ), &
3065 this%bare_soil_evap( cell_indx ), &
3066 this%direct_net_infiltration( cell_indx ), &
3067 this%direct_soil_moisture( cell_indx ), &
3068 (previous_5_day_rain(kndx), kndx=1,6)
3069
3070 enddo
3071
3072 flush(unit=unitnum)
3073
3074 end subroutine model_dump_variables
3075
3076!--------------------------------------------------------------------------------------------------
3077
3079
3081
3082 class(model_domain_t), intent(inout) :: this
3083
3084 call actual_et_gridded_values_initialize( this%active )
3085
3087
3088!--------------------------------------------------------------------------------------------------
3089
3091
3093 actual_et
3094
3095 class(model_domain_t), intent(inout) :: this
3096 integer (c_int), intent(in) :: indx
3097
3098 call actual_et_gridded_values_calculate( this%active )
3099
3100! this%actual_et(indx) = ACTUAL_ET(indx)
3101 this%actual_et_soil(indx) = max(actual_et(indx) - this%actual_et_interception(indx) &
3102 * this%canopy_cover_fraction(indx), 0.0_c_double)
3103
3105
3106!--------------------------------------------------------------------------------------------------
3107
3109
3110 class(model_domain_t), intent(inout) :: this
3111
3113
3114!--------------------------------------------------------------------------------------------------
3115
3117
3119
3120 class(model_domain_t), intent(inout) :: this
3121 integer (c_int), intent(in) :: indx
3122
3123 call calculate_actual_et_thornthwaite_mather( actual_et=this%actual_et_soil( indx ), &
3124 soil_storage=this%soil_storage( indx ), &
3125 soil_storage_max=this%soil_storage_max( indx ), &
3126 infiltration=this%infiltration( indx ), &
3127 crop_etc=this%crop_etc( indx ) )
3128
3130
3131!--------------------------------------------------------------------------------------------------
3132
3134
3136
3137 class(model_domain_t), intent(inout) :: this
3138
3140
3142
3143!--------------------------------------------------------------------------------------------------
3144
3145 subroutine model_calculate_actual_et_fao56( this, indx )
3146
3148
3149 class(model_domain_t), intent(inout) :: this
3150 integer (c_int), intent(in) :: indx
3151
3152 ! [ LOCALS ]
3153 integer (c_int) :: landuse_index
3154
3155 landuse_index = this%landuse_index( indx )
3156
3157 call calculate_actual_et_fao56( actual_et=this%actual_et_soil( indx ), &
3158 adjusted_depletion_fraction_p=this%adjusted_depletion_fraction_p( indx ), &
3159 soil_storage=this%soil_storage( indx ), &
3160 soil_storage_max=this%soil_storage_max( indx ), &
3161 infiltration=this%infiltration( indx ), &
3162 crop_etc=this%crop_etc( indx ), &
3163 depletion_fraction_p=depletion_fraction( landuse_index ) )
3164
3165 end subroutine model_calculate_actual_et_fao56
3166
3167 !--------------------------------------------------------------------------------------------------
3168
3170
3172
3173 class(model_domain_t), intent(inout) :: this
3174
3176
3178
3179 !--------------------------------------------------------------------------------------------------
3180
3182
3184
3185 class(model_domain_t), intent(inout) :: this
3186 integer (c_int), intent(in) :: indx
3187
3188 ! [ LOCALS ]
3189 integer (c_int) :: landuse_index
3190
3191 landuse_index = this%landuse_index( indx )
3192
3194 actual_et=this%actual_et_soil( indx ), &
3195 crop_etc=this%crop_etc( indx ), &
3196 bare_soil_evap=this%bare_soil_evap( indx ), &
3197 taw=this%total_available_water_taw( indx ), &
3198 raw=this%readily_available_water_raw( indx ), &
3199 fraction_exposed_and_wetted_soil=this%fraction_exposed_and_wetted_soil( indx ), &
3200 kr=this%evap_reduction_coef_kr( indx ), &
3201 ke=this%surf_evap_coef_ke( indx ), &
3202 ks=this%plant_stress_coef_ks( indx ), &
3203 adjusted_depletion_fraction_p=this%adjusted_depletion_fraction_p( indx ), &
3204 soil_moisture_deficit=this%soil_moisture_deficit( indx ), &
3205 current_plant_height=this%current_plant_height( indx ), &
3206 evaporable_water_storage=this%evaporable_water_storage( indx ), &
3207 evaporable_water_deficit=this%evaporable_water_deficit( indx ), &
3208 it_is_growing_season=this%it_is_growing_season( indx ), &
3209 kcb=this%crop_coefficient_kcb( indx ), &
3210 landuse_index=this%landuse_index( indx ), &
3211 soil_group=this%soil_group( indx ), &
3212 awc=this%awc( indx ), &
3213 current_rooting_depth=this%current_rooting_depth( indx ), &
3214 soil_storage=this%soil_storage( indx ), &
3215 soil_storage_max=this%soil_storage_max( indx ), &
3216 reference_et0=max(this%reference_et0( indx ) &
3217 - this%actual_et_interception( indx ), 0.0_c_double), &
3218 infiltration=this%infiltration( indx ) )
3219
3221
3222!--------------------------------------------------------------------------------------------------
3223
3225
3226 class(model_domain_t), intent(inout) :: this
3227
3229
3230!--------------------------------------------------------------------------------------------------
3231
3233
3234 class(model_domain_t), intent(inout) :: this
3235 integer ( c_int ), intent(in) :: indx
3236
3238
3239!--------------------------------------------------------------------------------------------------
3240
3242
3244
3245 class(model_domain_t), intent(inout) :: this
3246
3247 call direct_net_infiltration_initialize( is_cell_active=this%active, &
3248 landuse_index=this%landuse_index )
3249
3251
3252!--------------------------------------------------------------------------------------------------
3253
3255
3257
3258 class(model_domain_t), intent(inout) :: this
3259 integer ( c_int ), intent(in) :: indx
3260
3261 call direct_net_infiltration_calculate( direct_net_infiltration = this%direct_net_infiltration( indx ), &
3262 indx=indx, &
3263 is_cell_active=this%active, &
3264 nodata_fill_value=this%nodata_fill_value )
3265
3267
3268!--------------------------------------------------------------------------------------------------
3269
3271
3272 class(model_domain_t), intent(inout) :: this
3273
3275
3276!--------------------------------------------------------------------------------------------------
3277
3279
3280 class(model_domain_t), intent(inout) :: this
3281 integer ( c_int ), intent(in) :: indx
3282
3284
3285!--------------------------------------------------------------------------------------------------
3286
3288
3290
3291 class(model_domain_t), intent(inout) :: this
3292
3293 call direct_soil_moisture_initialize( is_cell_active=this%active, &
3294 landuse_index=this%landuse_index )
3295
3297
3298!--------------------------------------------------------------------------------------------------
3299
3301
3303
3304 class(model_domain_t), intent(inout) :: this
3305 integer ( c_int ), intent(in) :: indx
3306
3307 call direct_soil_moisture_calculate( direct_soil_moisture = this%direct_soil_moisture( indx ), &
3308 indx=indx, &
3309 is_cell_active=this%active )
3310
3312
3313!--------------------------------------------------------------------------------------------------
3314
3316
3317 class(model_domain_t), intent(inout) :: this
3318
3320
3321!--------------------------------------------------------------------------------------------------
3322
3324
3325 class(model_domain_t), intent(inout) :: this
3326 integer ( c_int ), intent(in) :: indx
3327
3329
3330!--------------------------------------------------------------------------------------------------
3331
3333
3335
3336 class(model_domain_t), intent(inout) :: this
3337
3338 call maximum_net_infiltration_initialize( is_cell_active=this%active, &
3339 landuse_index=this%landuse_index )
3340
3342
3343!--------------------------------------------------------------------------------------------------
3344
3346
3348
3349 class(model_domain_t), intent(inout) :: this
3350 integer ( c_int ), intent(in) :: indx
3351
3352 call maximum_net_infiltration_calculate( net_infiltration = this%net_infiltration( indx ), &
3353 rejected_net_infiltration = this%rejected_net_infiltration( indx ), &
3354 indx=indx )
3355
3357
3358 !--------------------------------------------------------------------------------------------------
3359
3361
3362 class(model_domain_t), intent(inout) :: this
3363
3365
3366 !--------------------------------------------------------------------------------------------------
3367
3369
3370 class(model_domain_t), intent(inout) :: this
3371
3372 end subroutine model_update_rooting_depth_none
3373
3374 !--------------------------------------------------------------------------------------------------
3375
3377
3379
3380 class(model_domain_t), intent(inout) :: this
3381
3383
3385
3386 !--------------------------------------------------------------------------------------------------
3387
3388
3390
3392
3393 class(model_domain_t), intent(inout) :: this
3394
3395 call update_rooting_depth( &
3396 zr_i=this%current_rooting_depth, &
3397 zr_max=this%rooting_depth_max, &
3398 landuse_index=this%landuse_index, &
3399 kcb=this%crop_coefficient_kcb )
3400
3402
3403!--------------------------------------------------------------------------------------------------
3404
3406
3407 class(model_domain_t), intent(inout) :: this
3408
3409 this%crop_coefficient_kcb = 1.0_c_float
3410
3412
3413!--------------------------------------------------------------------------------------------------
3414
3416
3417 class(model_domain_t), intent(inout) :: this
3418
3420
3421!--------------------------------------------------------------------------------------------------
3422
3424
3426
3427 class(model_domain_t), intent(inout) :: this
3428
3430
3432
3433!--------------------------------------------------------------------------------------------------
3434
3436
3440
3441 class(model_domain_t), intent(inout) :: this
3442
3443 ! [ LOCALS ]
3444 integer (c_int) :: indx
3445
3447
3448 do indx=1,ubound(this%number_of_days_since_planting,1)
3449
3450 this%number_of_days_since_planting(indx) = int(sim_dt%curr &
3451 - growth_stage_date( planting_date, this%landuse_index(indx) ), c_int)
3452 enddo
3453
3454
3455 call crop_coefficients_fao56_calculate( kcb=this%crop_coefficient_kcb, &
3456 gdd=this%gdd, &
3457 landuse_index=this%landuse_index )
3458
3460
3461!--------------------------------------------------------------------------------------------------
3462
3464
3465 class(model_domain_t), intent(inout) :: this
3466
3467 !> Nothing here to see. Initialization not really needed for the "normal" method.
3468 this%fog = 0.0_c_float
3469
3470 end subroutine model_initialize_fog_none
3471
3472!--------------------------------------------------------------------------------------------------
3473
3475
3477
3478 class(model_domain_t), intent(inout) :: this
3479
3480 call fog_monthly_grid_initialize( lactive=this%active )
3481
3483
3484!--------------------------------------------------------------------------------------------------
3485
3487
3488 class(model_domain_t), intent(inout) :: this
3489
3490 !> Nothing here to see. Initialization not really needed for the "normal" method.
3491
3492 end subroutine model_initialize_precip_normal
3493
3494!--------------------------------------------------------------------------------------------------
3495
3497
3499
3500 class(model_domain_t), intent(inout) :: this
3501
3503
3504 end subroutine model_initialize_precip_tabular
3505
3506!--------------------------------------------------------------------------------------------------
3507
3509
3510 class(model_domain_t), intent(inout) :: this
3511
3512 end subroutine model_calculate_fog_none
3513
3514!--------------------------------------------------------------------------------------------------
3515
3517
3519
3520 class(model_domain_t), intent(inout) :: this
3521
3522 call fog_monthly_grid_calculate( frainfall=this%rainfall, ffog=this%fog, &
3523 ilanduse_index=this%landuse_index, lactive=this%active, &
3524 nodata_fill_value=this%nodata_fill_value )
3525
3527
3528!--------------------------------------------------------------------------------------------------
3529
3531
3532 class( model_domain_t ), intent(inout) :: this
3533
3534 this%tmean = ( this%tmin + this%tmax ) / 2.0_c_float
3535
3537
3538!--------------------------------------------------------------------------------------------------
3539
3541
3542 class( model_domain_t ), intent(inout) :: this
3543
3544 this%tmax_minus_tmin = this%tmax - this%tmin
3545
3547
3548!--------------------------------------------------------------------------------------------------
3549
3550 subroutine model_calculate_climatic_water_deficit(this, cell_index)
3551
3552 class(model_domain_t), intent(inout) :: this
3553 integer (c_int), intent(in) :: cell_index
3554
3555 if (this%reference_et0(cell_index) > this%actual_et(cell_index)) then
3556 this%climatic_deficit(cell_index) = real(this%reference_et0(cell_index) - this%actual_et(cell_index), c_float)
3557 else
3558 this%climatic_deficit(cell_index) = 0.0_c_float
3559 endif
3560
3562
3563!--------------------------------------------------------------------------------------------------
3564
3566
3567 class(model_domain_t), intent(inout) :: this
3568
3569 type (DATA_CATALOG_ENTRY_T), pointer :: pTMAX
3570
3571 ptmax => dat%find("TMAX")
3572 if ( .not. associated(ptmax) ) &
3573 call die("INTERNAL PROGRAMMING ERROR: attempted use of NULL pointer", __file__, __line__)
3574
3575 associate( dt => sim_dt%curr )
3576
3577 call ptmax%getvalues( dt )
3578
3579 end associate
3580
3581 if (.not. associated(ptmax%pGrdBase) ) &
3582 call die("INTERNAL PROGRAMMING ERROR: Call to NULL pointer.", __file__, __line__)
3583
3584 this%tmax = pack( ptmax%pGrdBase%rData, this%active )
3585
3587
3588!--------------------------------------------------------------------------------------------------
3589
3591
3593
3594 class(model_domain_t), intent(inout) :: this
3595 real (kind=c_float) :: tmax_value
3596
3597 associate( dt => sim_dt%curr )
3598
3599 call weather_data_tabular_get_tmax( dt, tmax_value )
3600
3601 end associate
3602
3603 if (.not. allocated(this%tmax)) allocate(this%tmax(count(this%active)))
3604
3605 this%tmax = tmax_value
3606
3608
3609!--------------------------------------------------------------------------------------------------
3610
3612
3613 class(model_domain_t), intent(inout) :: this
3614
3615 type (DATA_CATALOG_ENTRY_T), pointer :: pTMIN
3616
3617 ptmin => dat%find("TMIN")
3618 if ( .not. associated(ptmin) ) &
3619 call die("INTERNAL PROGRAMMING ERROR: attempted use of NULL pointer", __file__, __line__)
3620
3621 associate( dt => sim_dt%curr )
3622
3623 call ptmin%getvalues( dt )
3624
3625 end associate
3626
3627 if (.not. associated(ptmin%pGrdBase) ) &
3628 call die("INTERNAL PROGRAMMING ERROR: Call to NULL pointer.", __file__, __line__)
3629
3630 this%tmin = pack( ptmin%pGrdBase%rData, this%active )
3631
3633
3634!--------------------------------------------------------------------------------------------------
3635
3637
3639
3640 class(model_domain_t), intent(inout) :: this
3641 real (kind=c_float) :: tmin_value
3642
3643 associate( dt => sim_dt%curr )
3644
3645 call weather_data_tabular_get_tmin( dt, tmin_value )
3646
3647 end associate
3648
3649 if (.not. allocated(this%tmin)) allocate(this%tmin(count(this%active)))
3650
3651 this%tmin = tmin_value
3652
3653
3655
3656!--------------------------------------------------------------------------------------------------
3657
3659
3660 class(model_domain_t), intent(inout) :: this
3661
3662 ! [ LOCALS ]
3663 type (DATA_CATALOG_ENTRY_T), pointer :: pPRCP
3664
3665 pprcp => dat%find("PRECIPITATION")
3666 if ( .not. associated(pprcp) ) &
3667 call die("INTERNAL PROGRAMMING ERROR: attempted use of NULL pointer", __file__, __line__)
3668
3669 associate( dt => sim_dt%curr )
3670
3671 call pprcp%getvalues( dt )
3672
3673 end associate
3674
3675 if (.not. associated(pprcp%pGrdBase) ) &
3676 call die("INTERNAL PROGRAMMING ERROR: Call to NULL pointer.", __file__, __line__)
3677
3678 this%gross_precip = pack( pprcp%pGrdBase%rData, this%active )
3679
3680 end subroutine model_get_precip_normal
3681
3682!--------------------------------------------------------------------------------------------------
3683
3685
3687
3688 class(model_domain_t), intent(inout) :: this
3689 real (kind=c_float) :: precip_value
3690
3691 associate( dt => sim_dt%curr )
3692
3693 call weather_data_tabular_get_precip( dt, precip_value )
3694
3695 end associate
3696
3697 if (.not. allocated(this%gross_precip)) allocate(this%gross_precip(count(this%active)))
3698 this%gross_precip = precip_value
3699
3700 end subroutine model_get_precip_tabular
3701
3702!--------------------------------------------------------------------------------------------------
3703
3705
3707
3708 class(model_domain_t), intent(inout) :: this
3709
3710 ! [ LOCALS ]
3711 integer (c_int) :: status
3712
3713 allocate( this%monthly_gross_precip( count( this%active ) ), stat=status)
3714 call assert( status==0, "Problem allocating memory", __file__, __line__ )
3715
3717 !call this%get_precipitation_data()
3718
3720
3721!--------------------------------------------------------------------------------------------------
3722
3724
3726
3727 class(model_domain_t), intent(inout) :: this
3728
3729 ! [ LOCALS ]
3730 type (DATA_CATALOG_ENTRY_T), pointer :: pPRCP
3731
3732 ! in this usage, it is assumed that the precipitation grids that are being read in represent
3733 ! MONTHLY sum of precipitation
3734 pprcp => dat%find("PRECIPITATION")
3735 if ( .not. associated(pprcp) ) &
3736 call die("INTERNAL PROGRAMMING ERROR: attempted use of NULL pointer", __file__, __line__)
3737
3738 associate( dt => sim_dt%curr )
3739
3740 ! get current grid value for precip; in the design case, this is a grid of MONTHLY
3741 ! mean precipitation totals in inches
3742 call pprcp%getvalues( dt )
3743
3744 end associate
3745
3746 if (.not. associated(pprcp%pGrdBase) ) &
3747 call die("INTERNAL PROGRAMMING ERROR: attempted use of NULL pointer.", __file__, __line__)
3748
3749 call precipitation_method_of_fragments_calculate( this%active )
3750
3751 this%gross_precip = pack( pprcp%pGrdBase%rData, this%active ) * fragment_value * rainfall_adjust_factor
3752 this%monthly_gross_precip = pack( pprcp%pGrdBase%rData, this%active ) * rainfall_adjust_factor
3753
3754 ! print *, "*****************************************************************"
3755 ! do indexval=5,7
3756
3757 ! targetindex = this%row_column_to_index_fn( indexval, 151 )
3758
3759 ! if ( targetindex > 0 ) then
3760
3761 ! print *, " row 151, col ", indexval
3762 ! print *, "----------------"
3763 ! print *, "active?: ", this%active( indexval,151 )
3764 ! print *, "gross_precip: ", this%gross_precip( targetindex )
3765 ! print *, "FRAGMENT_VALUE: ", FRAGMENT_VALUE( targetindex )
3766 ! print *, "RAIN_ADJST_FAC: ", RAINFALL_ADJUST_FACTOR( targetindex )
3767 ! print *, "Raw PRCP grid: ", pPRCP%pGrdBase%rData( indexval, 151 )
3768 ! print *, "Rain Gage ID: ", RAIN_GAGE_ID( targetindex )
3769 ! print *, " "
3770 ! endif
3771
3772 ! enddo
3773
3774 ! print *, "*****************************************************************"
3775
3777
3778!--------------------------------------------------------------------------------------------------
3779
3780 subroutine minmaxmean_float( variable , varname, active_cells )
3781
3782 real (c_float), dimension(:) :: variable
3783 character (len=*), intent(in) :: varname
3784 logical, dimension(:), optional :: active_cells
3785
3786 ! [ LOCALS ]
3787 character (len=20) :: sVarname
3788 character (len=14) :: sMin
3789 character (len=14) :: sMax
3790 character (len=14) :: sMean
3791 character (len=10) :: sCount
3792
3793 write (svarname, fmt="(a20)") adjustl(varname)
3794
3795 if ( present( active_cells ) ) then
3796
3797 if (count( active_cells ) > 0 ) then
3798 write (smin, fmt="(g14.3)") minval(variable, active_cells )
3799 write (smax, fmt="(g14.3)") maxval(variable, active_cells )
3800 write (smean, fmt="(g14.3)") sum(variable, active_cells ) / count( active_cells )
3801 write (scount, fmt="(i10)") count( active_cells )
3802 else
3803 write (smin, fmt="(g14.3)") -9999.
3804 write (smax, fmt="(g14.3)") -9999.
3805 write (smean, fmt="(g14.3)") -9999.
3806 write (scount, fmt="(i10)") 0
3807 endif
3808
3809 else
3810
3811 if (size( variable, 1) > 0 ) then
3812 write (smin, fmt="(g14.3)") minval(variable)
3813 write (smax, fmt="(g14.3)") maxval(variable)
3814 write (smean, fmt="(g14.3)") sum(variable) / size(variable,1)
3815 write (scount, fmt="(i10)") size(variable,1)
3816 else
3817 write (smin, fmt="(g14.3)") -9999.
3818 write (smax, fmt="(g14.3)") -9999.
3819 write (smean, fmt="(g14.3)") -9999.
3820 write (scount, fmt="(i10)") 0
3821 endif
3822
3823 endif
3824
3825 call logs%write( adjustl(svarname)//" | "//adjustl(smin)//" | "//adjustl(smax) &
3826 //" | "//adjustl(smean)//" | "//adjustl(scount), iloglevel=log_all, lecho=true )
3827
3828
3829 end subroutine minmaxmean_float
3830
3831
3832 subroutine minmaxmean_int( variable , varname, active_cells )
3833
3834 integer (c_int), dimension(:) :: variable
3835 character (len=*), intent(in) :: varname
3836 logical, dimension(:), optional :: active_cells
3837
3838 ! [ LOCALS ]
3839 character (len=20) :: sVarname
3840 character (len=14) :: sMin
3841 character (len=14) :: sMax
3842 character (len=14) :: sMean
3843 character (len=10) :: sCount
3844
3845 write (svarname, fmt="(a20)") adjustl(varname)
3846
3847 if ( present( active_cells ) ) then
3848
3849 if (count( active_cells ) > 0 ) then
3850 write (smin, fmt="(i14)") minval(variable, active_cells )
3851 write (smax, fmt="(i14)") maxval(variable, active_cells )
3852 write (smean, fmt="(i14)") sum(variable, active_cells ) / count( active_cells )
3853 write (scount, fmt="(i10)") count( active_cells )
3854 else
3855 write (smin, fmt="(i14)") -9999
3856 write (smax, fmt="(i14)") -9999
3857 write (smean, fmt="(i14)") -9999
3858 write (scount, fmt="(i10)") 0
3859 endif
3860
3861 else
3862
3863 if (size( variable, 1) > 0 ) then
3864 write (smin, fmt="(i14)") minval(variable)
3865 write (smax, fmt="(i14)") maxval(variable)
3866 write (smean, fmt="(i14)") sum(variable) / size(variable,1)
3867 write (scount, fmt="(i10)") size(variable,1)
3868 else
3869 write (smin, fmt="(i14)") -9999
3870 write (smax, fmt="(i14)") -9999
3871 write (smean, fmt="(i14)") -9999
3872 write (scount, fmt="(i10)") 0
3873 endif
3874
3875 endif
3876
3877 call logs%write( adjustl(svarname)//" | "//adjustl(smin)//" | "//adjustl(smax) &
3878 //" | "//adjustl(smean)//" | "//adjustl(scount), iloglevel=log_all, lecho=true )
3879
3880 end subroutine minmaxmean_int
3881
3883
3884 class(model_domain_t), intent(inout) :: this
3885
3886 call logs%write( "variable name | min | max | mean | count ")
3887 call logs%write( "-------------------- | -------------- | -------------- | -------------- | --------------")
3888
3889 call minmaxmean( this%landuse_code , "LULC")
3890 call minmaxmean( this%landuse_index, "LULC_index")
3891 call minmaxmean( this%soil_group, "HSG")
3892 call minmaxmean( this%num_upslope_connections, "upslope")
3893 call minmaxmean( this%sum_upslope_cells, "sum_upslope")
3894
3895 call minmaxmean( this%awc, "AWC")
3896
3897 call minmaxmean( this%latitude, "Lat")
3898 call minmaxmean( real(this%reference_ET0, c_float), "ET0")
3899 call minmaxmean( real( this%actual_ET, c_float), "actET")
3900 call minmaxmean( this%inflow, "inflow")
3901 call minmaxmean( this%runon, "runon")
3902 call minmaxmean( this%runoff, "runoff")
3903 call minmaxmean( this%outflow, "outflow")
3904 call minmaxmean( this%infiltration, "infilt")
3905 call minmaxmean( this%snowfall, "snowfall")
3906 call minmaxmean( this%snowmelt, "snowmelt")
3907 call minmaxmean( this%interception, "intercept")
3908 call minmaxmean( this%rainfall, "rainfall")
3909
3910 call minmaxmean( this%interception_storage, "intcp_stor")
3911 call minmaxmean( this%snow_storage, "snow_stor")
3912 call minmaxmean( real(this%soil_storage, c_float), "soil_stor")
3913 call minmaxmean( this%soil_storage_max, "soil_stor_max")
3914 call minmaxmean( this%net_infiltration, "net_infiltration")
3915
3916 end subroutine summarize_state_variables_sub
3917
3918!--------------------------------------------------------------------------------------------------
3919
3920end module model_domain
Calculates actual evapotranspiration by means of the SINGLE CROP COEFFICIENT procedure outlined in th...
elemental subroutine calculate_actual_et_fao56(actual_et, adjusted_depletion_fraction_p, soil_storage, depletion_fraction_p, soil_storage_max, infiltration, crop_etc)
subroutine initialize_actual_et_fao56()
real(c_float), dimension(:), allocatable depletion_fraction
Provide support for assessing the effect of irrigation on recharge values by estimating the irrigatio...
impure elemental subroutine calculate_actual_et_fao56_two_stage(actual_et, crop_etc, bare_soil_evap, taw, raw, fraction_exposed_and_wetted_soil, kr, ke, ks, adjusted_depletion_fraction_p, soil_moisture_deficit, evaporable_water_storage, evaporable_water_deficit, it_is_growing_season, kcb, landuse_index, soil_group, awc, current_rooting_depth, current_plant_height, soil_storage, soil_storage_max, reference_et0, infiltration)
Populate actual evapotranspiration by substituting in the daily average actual ET from a gridded data...
subroutine, public actual_et_gridded_values_initialize(is_cell_active)
subroutine, public actual_et_gridded_values_calculate(is_cell_active)
real(c_float), dimension(:), allocatable, public actual_et
Calculate actual ET by means of an approximation to the Thornthwaite-Mather soil-moisture-retention t...
elemental subroutine calculate_actual_et_thornthwaite_mather(actual_et, soil_storage, soil_storage_max, infiltration, crop_etc)
Populate the available water content by reading in and depth-averaging soil available water contents ...
subroutine, public awc_depth_integrated_initialize(lactive, fawc, isoils_code)
subroutine, public awc_depth_integrated_read(frooting_depth)
real(c_float), dimension(:,:), allocatable, public available_water_content
Populate available water content by reading in the available water content from a gridded data source...
subroutine, public awc_gridded_values_read()
subroutine, public awc_gridded_values_initialize(lactive, fawc)
This module contains physical constants and convenience functions aimed at performing unit conversion...
logical(c_bool), parameter, public true
logical(c_bool), parameter, public false
character(len=:), allocatable, public output_directory_name
subroutine, public initialize_continuous_frozen_ground_index(cfgi, cfgi_ll, cfgi_ul, active_cells)
elemental subroutine, public update_continuous_frozen_ground_index(fcfgi, ftmax_f, ftmin_f, fsnowcover)
Update the continuous frozen ground index (CFGI) for a cell.
Update crop coefficients for crop types in simulation.
subroutine, public crop_coefficients_fao56_initialize()
impure elemental subroutine, public crop_coefficients_fao56_update_growing_season(landuse_index, kcb, it_is_growing_season)
subroutine, public crop_coefficients_fao56_update_growth_stage_dates()
impure elemental subroutine, public crop_coefficients_fao56_calculate(kcb, landuse_index, gdd)
type(datetime_t), dimension(:,:), allocatable, public growth_stage_date
Defines the DATA_CATALOG_T data type, which contains type-bound procedures to add,...
type(data_catalog_t), public dat
DAT is a global to hold data catalog entries.
type(general_grid_t), pointer, public pgrd
integer(c_int), parameter, public dynamic_grid
This module contains the DATETIME_T class and associated time and date-related routines,...
Definition datetime.F90:9
Module direct_net_infiltration__gridded_data provides support for adding miscellaneous source and sin...
subroutine, public direct_net_infiltration_calculate(direct_net_infiltration, indx, is_cell_active, nodata_fill_value)
subroutine, public direct_net_infiltration_initialize(is_cell_active, landuse_index)
Initialize the routine to enable input/output of arbitrary sources/sink terms.
Module direct_soil_moisture__gridded_data provides support for adding miscellaneous source and sink t...
subroutine, public direct_soil_moisture_calculate(direct_soil_moisture, is_cell_active, indx)
subroutine, public direct_soil_moisture_initialize(is_cell_active, landuse_index)
Initialize the routine to enable input/output of arbitrary sources/sink terms to be added directly to...
Populate potential evapotranspiration by substituting in the daily average ET from a gridded data sou...
subroutine, public et_gridded_values_calculate()
type(data_catalog_entry_t), pointer, public pet_grid
subroutine, public et_gridded_values_initialize(lactive)
Calculates potential evapotranspiration by means of the Hargreaves-Samani (1985) method.
impure elemental real(c_double) function et_hargreaves_calculate(idayofyear, inumdaysinyear, flatitude, ftmin, ftmax)
Calculates potential evapotranspiration by means of the Jensen-Haise (1963) method.
elemental real(c_double) function, public et_jh_calculate(idayofyear, inumdaysinyear, flatitude, ftmin, ftmax, fas, fbs, fsunpct)
Module et__zone_values provides support for estimating reference ET given a zone map of ET_ZONE.
real(c_float), dimension(:), allocatable, public et_ratios
subroutine, public et_zone_values_initialize(lactive)
Initialize the ET grid.
type(data_catalog_entry_t), pointer, public pet_grid
subroutine, public et_zone_values_calculate()
subroutine, public warn(smessage, smodule, iline, shints, lfatal, iloglevel, lecho)
subroutine, public die(smessage, smodule, iline, shints, scalledby, icalledbyline)
Module fog__monthly_grid provides support for estimating fog drip given a gridded map of FOG_RATIO an...
subroutine, public fog_monthly_grid_initialize(lactive)
Initialize the fog drip algorithm.
subroutine, public fog_monthly_grid_calculate(frainfall, ffog, ilanduse_index, lactive, nodata_fill_value)
Provides support for input and output of gridded ASCII data, as well as for creation and destruction ...
Definition grid.F90:8
real(c_float), parameter nc_fill_float
Definition grid.F90:34
type(general_grid_t) function, pointer, public grid_createsimple(inx, iny, rx0, ry0, rgridcellsize, idatatype)
Definition grid.F90:281
integer(c_int), parameter, public grid_datatype_int
Definition grid.F90:25
subroutine, public grid_destroy(pgrd)
Definition grid.F90:366
subroutine, public grid_writearcgrid(sfilename, pgrd)
Definition grid.F90:1054
integer(c_int), parameter, private row
Definition grid.F90:171
integer(c_int), parameter, public grid_datatype_real
Definition grid.F90:26
subroutine, public growing_degree_day_initialize(is_cell_active, landuse_index)
impure elemental subroutine, public modified_growing_degree_day_calculate(gdd, tmin, tmax, order)
impure elemental subroutine, public growing_degree_day_calculate(gdd, tmean, order)
subroutine, public growing_degree_day_be_calculate(gdd, tmean, tmin, tmax, order)
subroutine, public growing_degree_day_be_initialize(is_cell_active, landuse_index)
elemental subroutine, public growing_season_update(landuse_index, gdd, mean_air_temp, it_is_growing_season)
subroutine, public growing_season_initialize()
real(c_float), dimension(:), allocatable, public bucket_interception_storage_max_growing_season
real(c_float), dimension(:), allocatable, public bucket_interception_storage_max_nongrowing_season
elemental subroutine, public interception_bucket_calculate(ilanduseindex, fprecip, ffog, fcanopy_cover_fraction, it_is_growing_season, finterception)
subroutine, public interception_bucket_initialize(active_cells)
real(c_float), dimension(:), allocatable, public stemflow_fraction_table_values
real(c_float), dimension(:), allocatable, public trunk_storage_capacity_table_values
real(c_float), dimension(:), allocatable, public evaporation_to_rainfall_ratio
subroutine, public interception_gash_initialize(lactive, fcanopy_cover_fraction, ilanduseindex)
Initialize the Gash interception algorithm.
real(c_float), dimension(:), allocatable, public gash_interception_storage_max_nongrowing_season
real(c_float), dimension(:), allocatable, public p_sat
elemental subroutine, public interception_gash_calculate(frainfall, ffog, fcanopy_cover_fraction, ftrunk_storage_capacity, fstemflow_fraction, fevaporation_to_rainfall_ratio, fprecipitation_at_saturation, finterception)
real(c_float), dimension(:), allocatable, public gash_interception_storage_max_growing_season
Provides support for assessing the effect of irrigation on recharge values by estimating the irrigati...
Definition irrigation.F90:8
impure elemental subroutine, public irrigation__calculate(irrigation_amount, landuse_index, soil_storage, soil_storage_max, total_available_water, rainfall, runoff, crop_etc, irrigation_mask, num_days_since_planting, monthly_rainfall, monthly_runoff)
subroutine, public irrigation__initialize(is_active)
Estimate the irrigation water required to sustain plant growth.
type(logfile_t), public logs
Definition logfiles.F90:62
Module maximum_net_infiltration__gridded_data provides support for adding miscellaneous source and si...
subroutine, public maximum_net_infiltration_initialize(is_cell_active, landuse_index)
Initialize the routine to establish maximum potential recharge rates.
elemental subroutine, public maximum_net_infiltration_calculate(net_infiltration, rejected_net_infiltration, indx)
subroutine model_initialize_direct_soil_moisture_gridded(this)
subroutine model_initialize_et_hargreaves(this)
subroutine model_initialize_snowfall_prms(this)
subroutine initialize_row_column_indices_sub(this)
subroutine model_initialize_snowfall_original(this)
subroutine model_initialize_snowmelt_original(this)
subroutine set_default_procedure_pointers_sub(this)
subroutine model_read_available_water_content_gridded(this)
subroutine model_initialize_routing_d8(this)
subroutine model_initialize_precip_method_of_fragments(this)
subroutine model_calculate_maximum_net_infiltration_none(this, indx)
integer(c_int) function row_column_to_index_fn(this, col_num, row_num)
subroutine model_update_growing_season_crop_coefficient_fao56(this)
subroutine model_calculate_direct_net_infiltration_none(this, indx)
subroutine model_get_precip_normal(this)
subroutine model_initialize_soil_storage_max_gridded(this)
subroutine model_calculate_snowfall_original(this)
subroutine initialize_methods_sub(this)
subroutine initialize_arrays_sub(this)
subroutine model_calculate_et_hargreaves(this)
subroutine model_initialize_continuous_frozen_ground_index(this)
subroutine model_calculate_modified_gdd(this)
subroutine model_update_rooting_depth_fao56(this)
subroutine model_calculate_gdd_none(this)
subroutine model_initialize_available_water_content_gridded(this)
subroutine model_calculate_maximum_net_infiltration_gridded(this, indx)
subroutine model_update_irrigation_mask(this)
subroutine model_calculate_direct_soil_moisture_none(this, indx)
subroutine, public initialize_landuse_codes()
Match landuse codes from table with those contained in the gridded landuse.
subroutine model_update_landuse_codes_dynamic(this)
subroutine model_initialize_soil_storage_max_internally_calculated(this)
subroutine model_initialize_precip_normal(this)
subroutine model_calculate_actual_et_fao56__two_stage(this, indx)
subroutine model_calculate_routing_d8(this, indx)
subroutine model_calculate_snowmelt_prms(this)
subroutine model_initialize_actual_et_gridded_values(this)
subroutine model_initialize_direct_soil_moisture_none(this)
subroutine model_calculate_et_daily_grid(this)
subroutine model_initialize_direct_net_infiltration_none(this)
subroutine model_update_rooting_depth_none(this)
subroutine model_calculate_runoff_gridded_values(this, indx)
subroutine model_calculate_actual_et_gridded_values(this, indx)
subroutine model_initialize_crop_coefficient_none(this)
subroutine model_initialize_irrigation_none(this)
subroutine model_initialize_actual_et_fao56(this)
subroutine model_calculate_irrigation(this, indx)
subroutine model_calculate_snowmelt_original(this)
subroutine model_initialize_actual_et_fao56__two_stage(this)
type(model_domain_t), public model
subroutine model_initialize_gdd_none(this)
type(cell_col_row_t), dimension(:), allocatable temp_dump
subroutine set_method_pointers_sub(this, scmdtext, argv_list)
subroutine model_initialize_et_monthly_zone_grid(this)
subroutine model_initialize_gdd_be(this)
subroutine model_initialize_runoff_gridded_values(this)
subroutine model_initialize_rooting_depth_none(this)
subroutine model_dump_variables(this, unitnum, indx_start, indx_end)
subroutine preflight_check_method_pointers(this)
subroutine model_output_irrigation_none(this)
subroutine model_calculate_direct_soil_moisture_gridded(this, indx)
subroutine model_initialize_precip_tabular(this)
subroutine model_update_crop_coefficient_fao56(this)
subroutine model_get_minimum_air_temperature_normal(this)
subroutine model_initialize_et_jensen_haise(this)
type(cell_col_row_t), dimension(:), allocatable dump
subroutine set_inactive_cells_sub(this)
subroutine model_get_maximum_air_temperature_tabular(this)
subroutine model_calculate_et_monthly_zone_grid(this)
subroutine model_initialize_irrigation(this)
subroutine model_get_minimum_air_temperature_tabular(this)
subroutine model_get_precip_method_of_fragments(this)
subroutine model_update_rooting_depth_table_sub(this)
subroutine model_read_available_water_content_depth_integrated(this)
subroutine model_initialize_maximum_net_infiltration_gridded(this)
subroutine model_calculate_snowfall_prms(this)
subroutine model_initialize_snowmelt_prms(this)
subroutine model_update_landuse_codes_static(this)
subroutine get_weather_data(this)
subroutine model_calculate_et_jensen_haise(this)
subroutine model_calculate_gdd_be(this)
subroutine model_initialize_et_daily_grid(this)
subroutine model_calculate_et_monthly_grid(this)
subroutine model_initialize_interception_gash(this)
subroutine model_calculate_runoff_curve_number(this, cell_index)
subroutine model_initialize_runoff_curve_number(this)
subroutine model_calculate_interception_gash(this)
subroutine model_initialize_fog_none(this)
subroutine model_calculate_gdd(this)
type(general_grid_t), pointer prooting_depth
subroutine model_calculate_actual_et_fao56(this, indx)
subroutine model_calculate_climatic_water_deficit(this, cell_index)
subroutine model_calculate_range_in_air_temperature(this)
subroutine model_initialize_crop_coefficient_fao56(this)
subroutine model_initialize_actual_et_thornthwaite_mather(this)
subroutine model_initialize_maximum_net_infiltration_none(this)
subroutine model_get_maximum_air_temperature_normal(this)
subroutine model_dump_variables_none(this)
subroutine model_initialize_gdd(this)
subroutine model_initialize_available_water_content_depth_integrated(this)
subroutine model_initialize_fog_monthly_grid(this)
subroutine model_dump_variables_by_cell(this)
subroutine model_calculate_interception_bucket(this)
subroutine model_calculate_fog_none(this)
subroutine, public read_landuse_codes
subroutine model_calculate_continuous_frozen_ground_index(this)
subroutine set_output_directory_sub(this, output_dir_name)
subroutine model_calculate_irrigation_none(this, indx)
subroutine model_initialize_et_monthly_grid(this)
subroutine minmaxmean_float(variable, varname, active_cells)
subroutine initialize_grid_sub(this, inumcols, inumrows, dx_ll, dy_ll, dgridcellsize)
subroutine model_calculate_direct_net_infiltration_gridded(this, indx)
subroutine model_initialize_rooting_depth_fao56(this)
subroutine model_get_precip_tabular(this)
subroutine minmaxmean_int(variable, varname, active_cells)
subroutine summarize_state_variables_sub(this)
subroutine model_calculate_actual_et_thornthwaite_mather(this, indx)
subroutine model_update_growing_season(this)
subroutine model_initialize_growing_season(this)
real(c_float), dimension(:,:), allocatable, public rooting_depth_max
subroutine model_update_crop_coefficient_none(this)
subroutine model_initialize_routing_none(this)
subroutine model_calculate_fog_monthly_grid(this)
subroutine model_initialize_direct_net_infiltration_gridded(this)
subroutine model_calculate_mean_air_temperature(this)
subroutine model_initialize_growing_season_crop_coefficient_fao56(this)
subroutine model_calculate_routing_none(this, indx)
subroutine model_initialize_interception_bucket(this)
Provide support for use of netCDF files as input for time-varying, gridded meteorlogic data,...
type(parameters_t), public params
type(dict_t), public params_dict
Module precipitation__method_of_fragments provides support for creating synthetic daily precipitation...
subroutine, public precipitation_method_of_fragments_initialize(lactive)
Initialize method of fragments.
elemental subroutine, public update_rooting_depth(zr_i, zr_max, landuse_index, kcb)
Calculate the effective root zone depth.
subroutine, public initialize_rooting_depth()
integer(c_int), dimension(:,:), allocatable, public number_of_upslope_connections
integer(c_int), dimension(:,:), allocatable, public sum_of_upslope_cells
elemental integer(c_int) function, public get_target_index(iteration_index)
elemental integer(c_int) function, public get_sort_order(cell_index)
subroutine, public routing_d8_initialize(lactive, sort_order)
elemental integer(c_int) function, public get_cell_index(iteration_index)
elemental subroutine, public runoff_curve_number_calculate(runoff, curve_num_adj, cell_index, landuse_index, soil_group, it_is_growing_season, inflow, soil_storage_max, continuous_frozen_ground_index, cfgi_lower_limit, cfgi_upper_limit)
Calculate the runoff by means of the curve number method.
real(c_float), dimension(:,:), allocatable, public prev_5_days_rain
subroutine, public update_previous_5_day_rainfall(infil, indx)
subroutine, public runoff_curve_number_initialize(cell_is_active)
Module runoff__gridded_values provides support for estimating fog drip given a gridded map of RUNOFF_...
subroutine, public runoff_gridded_values_initialize(lactive)
Initialize the infiltration grid.
subroutine, public runoff_gridded_values_update_ratios()
real(c_float), dimension(:), allocatable, public runoff_ratios
type(date_range_t), public sim_dt
elemental subroutine, public snowmelt_original_calculate(potential_snowmelt, tmin, tmax, imperial_units)
subroutine weather_data_tabular_initialize()
subroutine weather_data_tabular_get_tmin(dt, tmin_value)
subroutine weather_data_tabular_get_precip(dt, precip_value)
subroutine weather_data_tabular_get_tmax(dt, tmax_value)