Soil Water Balance (SWB2)
Loading...
Searching...
No Matches
interception__gash.F90
Go to the documentation of this file.
2
3 use iso_c_binding, only : c_short, c_int, c_float, c_double
7 use dictionary
8 use exceptions
10 use parameters, only : params
11 use grid
14 use fstring
15 use fstring_list
16 implicit none
17
18 private
19
24 p_sat, &
27
31
33
34 real (c_float), allocatable :: evaporation_to_rainfall_ratio(:)
35
36 real (c_float), allocatable :: canopy_storage_capacity_table_values(:)
37 real (c_float), allocatable :: trunk_storage_capacity_table_values(:)
38 real (c_float), allocatable :: stemflow_fraction_table_values(:)
39 real (c_float), allocatable :: gash_interception_storage_max_growing_season(:)
40 real (c_float), allocatable :: gash_interception_storage_max_nongrowing_season(:)
41
42 real (c_float), allocatable :: p_sat(:)
43
44 type (t_netcdf4_file), pointer :: pncfile ! pointer to OUTPUT NetCDF file
45
46contains
47
48 !> Initialize the Gash interception algorithm.
49 !!
50 !! Read in a canopy cover fraction and rainfall-to-evaporation ratio grids
51 !!
52 subroutine interception_gash_initialize( lActive, fCanopy_Cover_Fraction, iLandUseIndex )
53
54 logical (c_bool), intent(in) :: lactive(:,:)
55 real (c_float), intent(in) :: fcanopy_cover_fraction(:)
56 integer (c_int), intent(in) :: ilanduseindex(:)
57
58 ! [ LOCALS ]
59 integer (c_int) :: istat
60 type (fstring_list_t) :: sllist
61 integer (c_int) :: iindex
62 integer (c_int) :: icount
63 integer (c_int) :: inumrecs
64 integer (c_int), allocatable :: ilandusetablecodes(:)
65 integer (c_int) :: inumberoflanduses
66 logical (c_bool) :: larelengthsequal
67 real (c_float), allocatable :: tempvals(:)
68
69 icount = count( lactive )
70
71 allocate( evaporation_to_rainfall_ratio( icount ), stat=istat )
72 call assert( istat==0, "Problem allocating memory.", __file__, __line__ )
73
74 ! locate the data structure associated with the gridded evaporation to rainfall ratio
75 pevaporation_to_rainfall_ratio => dat%find("EVAPORATION_TO_RAINFALL_RATIO")
76 if ( .not. associated( pevaporation_to_rainfall_ratio ) ) &
77 call die("A EVAPORATION_TO_RAINFALL_RATIO grid must be supplied in order to" &
78 //" make use of this option.", __file__, __line__)
79
80
81 call pevaporation_to_rainfall_ratio%getvalues()
82
83 call grid_writearcgrid("Evaporation_to_Rainfall_Ratio__echo.asc", &
85
87
88 !! now grab the table values needed for this module
89
90 ! create list of possible table headings to look for...
91 call sllist%append( "LU_Code" )
92 call sllist%append( "Landuse_Lookup_Code" )
93
94 !> Determine how many landuse codes are present
95 call params%get_parameters( slkeys=sllist, ivalues=ilandusetablecodes )
96 inumberoflanduses = count( ilandusetablecodes >= 0 )
97
98 call sllist%clear()
99 call sllist%append("Canopy_Capacity")
100 call sllist%append("Canopy_Storage_Capacity")
101 call params%get_parameters( slkeys=sllist, fvalues=canopy_storage_capacity_table_values )
102
103 call sllist%clear()
104 call sllist%append("Trunk_Capacity")
105 call sllist%append("Trunk_Storage_Capacity")
106 call params%get_parameters( slkeys=sllist, fvalues=trunk_storage_capacity_table_values )
107
108 call sllist%clear()
109 call sllist%append("Stemflow_Fraction")
110 call sllist%append("Stemflow_Frac")
111 call params%get_parameters( slkeys=sllist, fvalues=stemflow_fraction_table_values )
112
113 inumrecs = ubound(canopy_storage_capacity_table_values,1)
114 larelengthsequal = ( inumrecs == inumberoflanduses )
115
116 !> retrieve interception storage max (GROWING SEASON)
117 call sllist%clear()
118 call sllist%append("interception_storage_max_growing")
119 call sllist%append("interception_storage_max_growing_season")
120 call sllist%append("interception_storage_maximum_growing")
121
122 call params%get_parameters( slkeys=sllist, &
124 lfatal=false )
125
127 larelengthsequal = ( inumrecs == inumberoflanduses )
128
129 if ( .not. larelengthsequal ) then
130 call warn( smessage="The number of landuses does not match the number of interception storage " &
131 //"maximum values for the growing season" &
132 //"('interception_storage_max_growing').", &
133 shints="A default value of 0.1 inches was assigned for the maximum interception storage", &
134 smodule=__file__, iline=__line__, lfatal=false )
135 allocate(tempvals(inumberoflanduses), stat=istat)
136 tempvals = 0.1
137 call move_alloc(tempvals, gash_interception_storage_max_growing_season)
138
139 endif
140
141 !> retrieve interception storage max (NONGROWING SEASON)
142 call sllist%clear()
143 call sllist%append("interception_storage_max_nongrowing")
144 call sllist%append("interception_storage_max_nongrowing_season")
145 call sllist%append("interception_storage_maximum_nongrowing")
146
147 call params%get_parameters( slkeys=sllist, &
149 lfatal=false )
150
152 larelengthsequal = ( inumrecs == inumberoflanduses )
153
154 if ( .not. larelengthsequal ) then
155 call warn( smessage="The number of landuses does not match the number of interception storage " &
156 //"maximum values for the nongrowing season" &
157 //"('interception_storage_max_nongrowing').", &
158 shints="A default value of 0.1 inches was assigned for the maximum interception storage", &
159 smodule=__file__, iline=__line__, lfatal=false )
160 allocate(tempvals(inumberoflanduses), stat=istat)
161 tempvals = 0.1
162 call move_alloc(tempvals, gash_interception_storage_max_nongrowing_season)
163 endif
164
165 !> @TODO add more guard code here to QA incoming data
166
167 if ( .not. larelengthsequal ) &
168 call warn( smessage="The number of canopy storage capacity values (" &
169 //ascharacter( inumrecs )//") does not match the number of landuse values (" &
170 //ascharacter( inumberoflanduses )//").", &
171 smodule=__file__, iline=__line__, lfatal=.true._c_bool )
172
173
174 inumrecs = ubound(trunk_storage_capacity_table_values,1)
175 larelengthsequal = ( inumrecs == inumberoflanduses )
176
177 if ( .not. larelengthsequal ) &
178 call warn( smessage="The number of trunk storage capacity values (" &
179 //ascharacter( inumrecs )//") does not match the number of landuse values (" &
180 //ascharacter( inumberoflanduses )//").", &
181 smodule=__file__, iline=__line__, lfatal=.true._c_bool )
182
183
184 inumrecs = ubound(stemflow_fraction_table_values,1)
185 larelengthsequal = ( inumrecs == inumberoflanduses )
186
187 if ( .not. larelengthsequal ) &
188 call warn( smessage="The number of stemflow fraction values (" &
189 //ascharacter( inumrecs )//") does not match the number of landuse values (" &
190 //ascharacter( inumberoflanduses )//").", &
191 smodule=__file__, iline=__line__, lfatal=.true._c_bool )
192
193
194 allocate( p_sat( count( lactive ) ), stat=istat )
195 call assert( istat==0, "Problem allocating memory for P_SAT.", __file__, __line__ )
196
198 canopy_storage_capacity_table_values( ilanduseindex ), &
199 fcanopy_cover_fraction )
200
201 end subroutine interception_gash_initialize
202
203!--------------------------------------------------------------------------------------------------
204
205 elemental function precipitation_at_saturation( E_div_P, canopy_storage_capacity, canopy_cover_fraction ) &
206 result( psat )
207
208 real (c_float), intent(in) :: e_div_p
209 real (c_float), intent(in) :: canopy_storage_capacity
210 real (c_float), intent(in) :: canopy_cover_fraction
211 real (c_float) :: psat
212
213 ! [ LOCALS ]
214 real (c_float) :: p_div_e
215
216 if ( canopy_cover_fraction > 0.0_c_float .and. canopy_storage_capacity > 0.0_c_float ) then
217
218 psat = - ( canopy_storage_capacity / ( canopy_cover_fraction * e_div_p ) ) &
219 * log( 1.0_c_float - e_div_p )
220 else
221
222 psat = 0.0_c_float
223
224 endif
225
226! !! calc Precip needed to saturate canopy
227! Psat=-( cancap( ilu(ip) ) / ( canfrac( ip )*cerf( ip ) ) ) &
228! * log( ( 1 - cerf( ip ) ) / ( 1 - ( 1 - ceint2 ) * cerf( ip ) ) )
229
230
231 end function precipitation_at_saturation
232
233!--------------------------------------------------------------------------------------------------
234
235 elemental subroutine interception_gash_calculate( fRainfall, fFog, fCanopy_Cover_Fraction, &
236 fTrunk_Storage_Capacity, fStemflow_Fraction, &
237 fEvaporation_to_Rainfall_Ratio, &
238 fPrecipitation_at_Saturation, fInterception )
239
240 real (c_float), intent(in) :: frainfall
241 real (c_float), intent(in) :: ffog
242 real (c_float), intent(in) :: fcanopy_cover_fraction
243 real (c_float), intent(in) :: ftrunk_storage_capacity
244 real (c_float), intent(in) :: fstemflow_fraction
245 real (c_float), intent(in) :: fevaporation_to_rainfall_ratio
246 real (c_float), intent(in) :: fprecipitation_at_saturation
247 real (c_float), intent(inout) :: finterception
248
249 ! [ LOCALS ]
250 real (c_float) :: frainfall_plus_fog
251
252 frainfall_plus_fog = frainfall + ffog
253
254 if ( fprecipitation_at_saturation .approxequal. 0.0_c_float ) then
255
256 finterception = 0.0_c_float
257
258 ! if(drf+dfog.lt.Psat)then
259 else if ( frainfall_plus_fog < fprecipitation_at_saturation ) then
260
261 ! dcanint=canfrac(ip)*(drf+dfog)
262 finterception = fcanopy_cover_fraction * frainfall_plus_fog
263
264! elseif(drf+dfog.gt.tcap(ilu(ip))/tfrac(ip))then
265 else if ( frainfall_plus_fog > ftrunk_storage_capacity &
266 / (fstemflow_fraction + 1.0e-6) ) then
267
268 finterception = fcanopy_cover_fraction * fprecipitation_at_saturation &
269 + fcanopy_cover_fraction * fevaporation_to_rainfall_ratio &
270 * ( frainfall_plus_fog - fprecipitation_at_saturation ) &
271 + ftrunk_storage_capacity
272
273
274 ! dcanint = canfrac(ip) * Psat
275 ! + canfrac(ip) * cerf(ip) * ( drf + dfog - Psat )
276 ! + tcap( ilu(ip) )
277
278 else
279
280 finterception = fcanopy_cover_fraction * fprecipitation_at_saturation &
281 + fcanopy_cover_fraction * fevaporation_to_rainfall_ratio &
282 * ( frainfall_plus_fog - fprecipitation_at_saturation ) &
283 + fstemflow_fraction * frainfall_plus_fog
284
285 ! dcanint = canfrac(ip) * Psat
286 ! + canfrac(ip) * cerf(ip) *( drf + dfog - Psat )
287 ! + tfrac(ip) * ( drf + dfog )
288
289 end if
290
291 finterception = min( finterception, frainfall_plus_fog )
292
293 !! HWB code:
294! !! calc Precip needed to saturate canopy
295! Psat=-( cancap( ilu(ip) ) / ( canfrac( ip )*cerf( ip ) ) ) &
296! * log( ( 1 - cerf( ip ) ) / ( 1 - ( 1 - ceint2 ) * cerf( ip ) ) )
297!
298! if ( drf + dfog .lt. Psat )then
299! dcanint = canfrac(ip) * ( drf + dfog )
300! elseif ( drf + dfog .gt. tcap( ilu(ip) ) / tfrac(ip) ) then
301! dcanint = canfrac(ip) * Psat + canfrac(ip) * cerf(ip) * ( drf + dfog - Psat ) + tcap( ilu(ip) )
302! else
303! dcanint = canfrac(ip) * Psat + canfrac(ip) * cerf(ip) *( drf + dfog - Psat ) + tfrac(ip) * ( drf + dfog )
304! endif
305!
306! dpnet = drf + dfog - dcanint
307
308 end subroutine interception_gash_calculate
309
310end module interception__gash
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
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)
subroutine, public die(smessage, smodule, iline, shints, scalledby, icalledbyline)
Provides support for input and output of gridded ASCII data, as well as for creation and destruction ...
Definition grid.F90:8
subroutine, public grid_writearcgrid(sfilename, pgrd)
Definition grid.F90:1056
elemental real(c_float) function, public precipitation_at_saturation(e_div_p, canopy_storage_capacity, canopy_cover_fraction)
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
type(t_netcdf4_file), pointer pncfile
real(c_float), dimension(:), allocatable, public canopy_storage_capacity_table_values
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
type(data_catalog_entry_t), pointer pevaporation_to_rainfall_ratio
Provide support for use of netCDF files as input for time-varying, gridded meteorlogic data,...
type(parameters_t), public params