3 use iso_c_binding,
only : c_short, c_int, c_float, c_double, c_long_long
19 real (c_float),
intent(inout) :: cfgi(:)
20 real (c_float),
intent(inout) :: cfgi_ll(:)
21 real (c_float),
intent(inout) :: cfgi_ul(:)
23 logical (c_bool),
intent(in) :: active_cells(:,:)
32 pinitial_cfgi =>
dat%find(
"INITIAL_CONTINUOUS_FROZEN_GROUND_INDEX")
34 if ( .not.
associated( pinitial_cfgi ) )
then
35 pinitial_cfgi =>
dat%find(
"INITIAL_FROZEN_GROUND_INDEX")
37 if ( .not.
associated( pinitial_cfgi ) )
then
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 )
49 call pinitial_cfgi%getvalues()
52 cfgi = pack( pinitial_cfgi%pGrdBase%rData, active_cells )
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 )
64 pcfgi_lower_limit =>
dat%find(
"CFGI_LOWER_LIMIT")
66 if ( .not.
associated( pcfgi_lower_limit ) )
then
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 )
76 call pcfgi_lower_limit%getvalues()
79 cfgi_ll = pack( pcfgi_lower_limit%pGrdBase%rData, active_cells )
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 )
90 pcfgi_upper_limit =>
dat%find(
"CFGI_UPPER_LIMIT")
92 if ( .not.
associated( pcfgi_upper_limit ) )
then
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 )
102 call pcfgi_upper_limit%getvalues()
105 cfgi_ul = pack( pcfgi_upper_limit%pGrdBase%rData, active_cells )
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 )
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)
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
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
150 real (c_float) :: ftavg_c
151 real (c_float) :: fsnowdepthcm
154 ftavg_c =
f_to_c( (ftmax_f + ftmin_f) / 2.0_c_float )
157 fsnowdepthcm = fsnowcover * 10.0_c_float * fcm_per_inch
159 associate( tavg => ftavg_c, &
160 a => fdecay_coefficient_a, &
162 k_freeze => fsnow_reduction_coefficient_freezing, &
163 k_thaw => fsnow_reduction_coefficient_thawing )
165 if( tavg > freezing_point_deg_c )
then
167 cfgi = max( a * cfgi - tavg * exp( -0.4_c_float * k_thaw * fsnowdepthcm ), 0.0_c_float )
171 cfgi = max( a * cfgi - tavg * exp( -0.4_c_float * k_freeze * fsnowdepthcm ), 0.0_c_float )
subroutine, public warn(smessage, smodule, iline, shints, lfatal, iloglevel, lecho)