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