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