Soil Water Balance (SWB2)
Loading...
Searching...
No Matches
continuous_frozen_ground_index.F90
Go to the documentation of this file.
2
3 use iso_c_binding, only : c_short, c_int, c_float, c_double, c_long_long
5 use data_catalog, only : dat
7
8 use exceptions
9 implicit none
10
11 private
12
14
15contains
16
17 subroutine initialize_continuous_frozen_ground_index( cfgi, cfgi_ll, cfgi_ul, active_cells )
18
19 real (c_float), intent(inout) :: cfgi(:)
20 real (c_float), intent(inout) :: cfgi_ll(:)
21 real (c_float), intent(inout) :: cfgi_ul(:)
22
23 logical (c_bool), intent(in) :: active_cells(:,:)
24
25 ! [ LOCALS ]
26 type (data_catalog_entry_t), pointer :: pinitial_cfgi
27 type (data_catalog_entry_t), pointer :: pcfgi_lower_limit
28 type (data_catalog_entry_t), pointer :: pcfgi_upper_limit
29 integer (c_int) :: i
30
31 ! locate the data structure associated with the gridded initial_cfgi
32 pinitial_cfgi => dat%find("INITIAL_CONTINUOUS_FROZEN_GROUND_INDEX")
33
34 if ( .not. associated( pinitial_cfgi ) ) then
35 pinitial_cfgi => dat%find("INITIAL_FROZEN_GROUND_INDEX")
36
37 if ( .not. associated( pinitial_cfgi ) ) then
38
39 call warn(smessage="An INITIAL_CONTINUOUS_FROZEN_GROUND_INDEX grid (or constant) was not found.", &
40 shints="Check your control file to see that a valid INITIAL_CONTINUOUS_FROZEN_GROUND_INDEX grid or" &
41 //" constant is specified.", lfatal=false )
42
43 cfgi = 0.0_c_float
44
45 endif
46
47 else
48
49 call pinitial_cfgi%getvalues()
50
51 ! map the 2D array of INITIAL_CFGI values to the vector of active cells
52 cfgi = pack( pinitial_cfgi%pGrdBase%rData, active_cells )
53
54 if ( minval( cfgi ) < fzero &
55 .or. maxval( cfgi ) > 300.0_c_float ) &
56 call warn(smessage="One or more initial continuous frozen ground values outside of " &
57 //"valid range (0 to 300)", lfatal=true )
58
59 endif
60
61
62
63 ! locate the data structure associated with the gridded CFGI_LOWER_LIMIT
64 pcfgi_lower_limit => dat%find("CFGI_LOWER_LIMIT")
65
66 if ( .not. associated( pcfgi_lower_limit ) ) then
67
68 call warn(smessage="No value supplied for CONTINUOUS_FROZEN_GROUND_INDEX_LOWER_LIMIT.", &
69 shints="Value set to the default of 56, which was appropriate for the Pacific Northwestern U.S., " &
70 //"but may be inappropriate elsewhere.", lfatal=false )
71
72 cfgi_ll = 56. ! units are degrees C-days
73
74 else
75
76 call pcfgi_lower_limit%getvalues()
77
78 ! map the 2D array of INITIAL_CFGI values to the vector of active cells
79 cfgi_ll = pack( pcfgi_lower_limit%pGrdBase%rData, active_cells )
80
81 if ( minval( cfgi_ll ) < fzero &
82 .or. maxval( cfgi_ll ) > 300.0_c_float ) &
83 call warn(smessage="One or more CFGI lower limit values outside of " &
84 //"valid range (0 to 300)", lfatal=true )
85
86 endif
87
88
89 ! locate the data structure associated with the gridded CFGI_UPPER_LIMIT
90 pcfgi_upper_limit => dat%find("CFGI_UPPER_LIMIT")
91
92 if ( .not. associated( pcfgi_upper_limit ) ) then
93
94 call warn(smessage="No value supplied for CONTINUOUS_FROZEN_GROUND_INDEX_UPPER_LIMIT.", &
95 shints="Value set to the default of 83, which was appropriate for the Pacific Northwestern U.S., " &
96 //"but may be inappropriate elsewhere.", lfatal=false )
97
98 cfgi_ul = 83. ! units are degree C-days
99
100 else
101
102 call pcfgi_upper_limit%getvalues()
103
104 ! map the 2D array of INITIAL_CFGI values to the vector of active cells
105 cfgi_ul = pack( pcfgi_upper_limit%pGrdBase%rData, active_cells )
106
107 if ( minval( cfgi_ul ) < fzero &
108 .or. maxval( cfgi_ul ) > 300.0_c_float ) &
109 call warn(smessage="One or more CFGI upper limit values outside of " &
110 //"valid range (0 to 300)", lfatal=true )
111
112 endif
113
114 if (any(cfgi_ul - cfgi_ll <= 0.0_c_float)) then
115 call warn(smessage="One or more CFGI upper limit values is less that its" &
116 //" corresponding CFGI lower limit values", lfatal=true)
117 endif
118
119
121
122!--------------------------------------------------------------------------------------------------
123
124 !> Update the continuous frozen ground index (CFGI) for a cell.
125 !!
126 !! Computes the continuous frozen ground index
127 !! @param[inout] rCFGI Continuous frozen ground index to be updated.
128 !! @param[in] rTAvg_F Mean daily air temperature, in \degF
129 !!
130 !! @note Implemented as per Molnau and Bissel (1983).
131 !!
132 !! @note Molnau, M. and Bissell, V.C., 1983, A continuous frozen ground index for
133 !! flood forecasting: In Proceedings 51st Annual Meeting Western Snow Conference,
134 !! 109-119, Canadian Water Resources Assoc. Cambridge, Ont.
135 elemental subroutine update_continuous_frozen_ground_index( fCFGI, fTMax_F, fTMin_F, fSnowCover )
136
137 ! [ ARGUMENTS ]
138 real (c_float), intent(inout) :: fcfgi
139 real (c_float), intent(in) :: ftmax_f
140 real (c_float), intent(in) :: ftmin_f
141 real (c_float), intent(in) :: fsnowcover
142
143 ! [ LOCALS ]
144 real (c_float), parameter :: fdecay_coefficient_a = 0.97_c_float
145 real (c_float), parameter :: fsnow_reduction_coefficient_freezing = 0.08_c_float
146 real (c_float), parameter :: fsnow_reduction_coefficient_thawing = 0.5_c_float
147 real (c_float), parameter :: fcm_per_inch = 2.54_c_float
148 real (c_float), parameter :: freezing_point_deg_c = 0.0_c_float
149
150 real (c_float) :: ftavg_c ! temporary variable holding avg temp in C
151 real (c_float) :: fsnowdepthcm ! snow depth in centimeters
152
153
154 ftavg_c = f_to_c( (ftmax_f + ftmin_f) / 2.0_c_float )
155
156 ! assuming snow depth is 10 times the water content of the snow in inches
157 fsnowdepthcm = fsnowcover * 10.0_c_float * fcm_per_inch
158
159 associate( tavg => ftavg_c, &
160 a => fdecay_coefficient_a, &
161 cfgi => fcfgi, &
162 k_freeze => fsnow_reduction_coefficient_freezing, &
163 k_thaw => fsnow_reduction_coefficient_thawing )
164
165 if( tavg > freezing_point_deg_c ) then
166
167 cfgi = max( a * cfgi - tavg * exp( -0.4_c_float * k_thaw * fsnowdepthcm ), 0.0_c_float )
168
169 else ! temperature is below freezing
170
171 cfgi = max( a * cfgi - tavg * exp( -0.4_c_float * k_freeze * fsnowdepthcm ), 0.0_c_float )
172
173 end if
174
175 end associate
176
178
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
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.
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.
subroutine, public warn(smessage, smodule, iline, shints, lfatal, iloglevel, lecho)