Soil Water Balance (SWB2)
Loading...
Searching...
No Matches
awc__depth_integrated.F90
Go to the documentation of this file.
1!> @file
2!> Contains the module awc__depth_integrated, which populates
3!! the available water content by reading in and depth-averaging
4!! soil available water contents over multiple soil horizons.
5
6
7!> Populate the available water content by reading in and depth-averaging
8!! soil available water contents over multiple soil horizons.
9
11
12 use iso_c_binding, only : c_short, c_int, c_float, c_double
14 use data_catalog
16 use exceptions
17 use parameters
18 use fstring
19 use fstring_list
20
21 implicit none
22
23 private
24
26
28 real (c_float), allocatable :: available_water_content(:,:)
29
30contains
31
32 subroutine awc_depth_integrated_read( fRooting_Depth )
33
34 real (c_float), intent(inout) :: frooting_depth(:,:)
35
36 ! [ LOCALS ]
37
38 integer (c_int), allocatable :: ilanduse_code(:)
39 integer (c_int), allocatable :: isoils_table_code(:)
40 integer (c_int), allocatable :: isoils_components(:)
41 integer (c_int), allocatable :: isoils_horizons(:)
42 real (c_float), allocatable :: fsoils_awc(:)
43 real (c_float), allocatable :: fsoils_top_depth(:)
44 real (c_float), allocatable :: fsoils_bottom_depth(:)
45 real (c_float), allocatable :: fsoils_component_fraction(:)
46 real (c_float), allocatable :: fsoils_horizon_thickness(:)
47
48 integer (c_int) :: inumberoflanduses
49 integer (c_int) :: inumberofsoils
50 integer (c_int) :: inumberofsoilscomponents
51 integer (c_int) :: inumberofsoilshorizons
52 integer (c_int) :: inumberofsoilsawc
53 integer (c_int) :: inumberofsoilstopdepths
54 integer (c_int) :: inumberofsoilsbottomdepths
55 integer (c_int) :: inumberofsoilscomponentfractions
56
57 real (c_float) :: ftemp_awc
58 real (c_float) :: fdepthofdeepesthorizon
59 real (c_float) :: ffinal_awc
60 integer (c_int) :: ideepestsoilhorizon
61 logical (c_bool) :: lfirst
62
63 type (fstring_list_t) :: sllist
64 integer (c_int) :: istat
65 integer (c_int) :: iindex, iindex2
66 integer (c_int) :: iindex_x, iindex_y
67 real (c_float) :: frooting_depth_inches
68
69 call sllist%append("LU_Code")
70 call sllist%append("Landuse_Code")
71 call sllist%append("Landuse_Lookup_Code")
72
73 call params%get_parameters( slkeys=sllist, ivalues=ilanduse_code )
74 inumberoflanduses = count( ilanduse_code >= 0 )
75 call sllist%clear()
76
77
78 call sllist%append("Soils_Code")
79 call sllist%append("Soils_Lookup_Code")
80 call sllist%append("Soil_Code")
81 call sllist%append("Soil_Lookup_Code")
82
83 call params%get_parameters( slkeys=sllist, ivalues=isoils_table_code )
84 inumberofsoils = count( isoils_table_code >= 0 )
85 call sllist%clear()
86
87 call sllist%append("Soils_Component")
88 call sllist%append("Soils_Component_Number")
89 call sllist%append("Soil_Component")
90 call sllist%append("Soil_Component_Number")
91
92 call params%get_parameters( slkeys=sllist, ivalues=isoils_components )
93 inumberofsoilscomponents = count( isoils_components >= 0 )
94 call sllist%clear()
95
96 call sllist%append("Soils_Top_Depth")
97 call sllist%append("Soil_Top_Depth")
98 call sllist%append("Soils_Z_Top")
99 call sllist%append("Soils_Top_of_Horizon")
100
101 call params%get_parameters( slkeys=sllist, fvalues=fsoils_top_depth )
102 inumberofsoilstopdepths = count( fsoils_top_depth >= 0 )
103 call sllist%clear()
104
105 call sllist%append("Soils_Bottom_Depth")
106 call sllist%append("Soil_Bottom_Depth")
107 call sllist%append("Soils_Z_Bottom")
108 call sllist%append("Soils_Bottom_of_Horizon")
109
110 call params%get_parameters( slkeys=sllist, fvalues=fsoils_bottom_depth )
111 inumberofsoilsbottomdepths = count( fsoils_bottom_depth >= 0 )
112 call sllist%clear()
113
114 call sllist%append("Soils_Horizon")
115 call sllist%append("Soils_Horizon_Number")
116 call sllist%append("Soil_Horizon")
117 call sllist%append("Soil_Horizon_Number")
118
119 call params%get_parameters( slkeys=sllist, ivalues=isoils_horizons )
120 inumberofsoilshorizons = count( isoils_horizons >= 0 )
121 call sllist%clear()
122
123 call sllist%append("Soils_Component_Fraction")
124 call sllist%append("Soil_Component_Fraction")
125
126 call params%get_parameters( slkeys=sllist, fvalues=fsoils_component_fraction )
127 inumberofsoilscomponentfractions = count( fsoils_component_fraction >= 0 )
128 call sllist%clear()
129
130
131 call sllist%append("Soils_Available_Water_Content")
132 call sllist%append("Soils_AWC")
133 call sllist%append("Soil_Available_Water_Content")
134 call sllist%append("Soil_AWC")
135 call sllist%append("Available_Water_Content")
136 call sllist%append("AWC")
137
138 call params%get_parameters( slkeys=sllist, fvalues=fsoils_awc )
139 inumberofsoilsawc = count( fsoils_awc >= 0 )
140 call sllist%clear()
141
142 !> @todo Need a *LOT* more data validation and guard code here to prevent execution in the case
143 !! where only some data fields are found, or are only partially populated.
144
145 ! locate the data structure associated with the gridded rainfall zone entries
146 psoils_code_grid => dat%find("SOILS_CODE")
147 call assert( associated(psoils_code_grid), &
148 "A SOILS_CODE grid must be supplied in order to make use of this option.", __file__, __line__)
149
150 call psoils_code_grid%getvalues( )
151
152 allocate (fsoils_horizon_thickness( ubound( fsoils_bottom_depth, 1) ), stat=istat )
153
154 allocate(available_water_content( ubound(frooting_depth, 1), ubound(frooting_depth, 2) ), stat=istat )
155
156 ! this should be in units of inches
157 fsoils_horizon_thickness = fsoils_bottom_depth - fsoils_top_depth
158
159 do iindex_x=lbound( frooting_depth, 1 ), ubound( frooting_depth, 1 )
160
161 do iindex_y=lbound( frooting_depth, 2 ), ubound( frooting_depth, 2 )
162
163 ! rooting depth in feet * 12 in/ft = rooting depth in inches
164 frooting_depth_inches = frooting_depth( iindex_x, iindex_y ) * 12.0_c_float
165
166 ftemp_awc = 0.0_c_float
167 lfirst = true
168 ideepestsoilhorizon = 0_c_int
169 fdepthofdeepesthorizon = 0.0_c_float
170 ffinal_awc = 0.0_c_float
171
172 do iindex=1, inumberofsoils
173 if ( psoils_code_grid%pGrdBase%iData( iindex_x, iindex_y ) == isoils_table_code( iindex ) ) then
174
175 ! look for current soil code; calculate the component-weighted mean AWC for the deepest horizon
176 if ( lfirst ) then
177
178 lfirst = false
179
180 ! find deepest soil horizon for the current soils code
181 do iindex2=iindex, inumberofsoils
182 if ( psoils_code_grid%pGrdBase%iData( iindex_x, iindex_y ) == isoils_table_code( iindex2 ) ) &
183 ideepestsoilhorizon = max( ideepestsoilhorizon, isoils_horizons( iindex2 ) )
184 enddo
185
186 ! if we are in the deepest horizon of the current soils code, calculate the composite averaged AWC
187 do iindex2=iindex, inumberofsoils
188 if ( ( psoils_code_grid%pGrdBase%iData( iindex_x, iindex_y ) == isoils_table_code( iindex2 ) ) &
189 .and. ( ideepestsoilhorizon == isoils_horizons( iindex2) ) ) &
190 ffinal_awc = ffinal_awc + fsoils_awc( iindex2 ) * fsoils_component_fraction( iindex2 )
191 fdepthofdeepesthorizon = fsoils_bottom_depth( iindex2 )
192 enddo
193
194 endif
195
196 ! rooting depth never reaches to this horizon; ignore
197 if ( frooting_depth_inches < fsoils_top_depth( iindex ) ) cycle
198
199 ! rooting depth exceeds lower bound of current horizon; entire horizon
200 ! depth used as weight factor
201 if ( frooting_depth_inches > fsoils_bottom_depth( iindex ) ) then
202
203 ftemp_awc = ftemp_awc + fsoils_awc( iindex ) * fsoils_component_fraction( iindex ) &
204 * fsoils_horizon_thickness( iindex )
205
206 ! rooting depth falls in between the upper and lower bounds of the current soil horizon
207 elseif ( frooting_depth_inches >= fsoils_top_depth( iindex ) &
208 .and. frooting_depth_inches <= fsoils_bottom_depth( iindex ) ) then
209
210 ftemp_awc = ftemp_awc + fsoils_awc( iindex ) * fsoils_component_fraction( iindex ) &
211 * ( frooting_depth_inches - fsoils_top_depth( iindex ) )
212
213 endif
214
215 endif
216
217 enddo
218
219 ! if the soil data from the table does not extend to the rooting depth, extrapolate
220 if (frooting_depth_inches > fdepthofdeepesthorizon ) &
221
222 ftemp_awc = ftemp_awc + ffinal_awc * ( frooting_depth_inches - fdepthofdeepesthorizon )
223
224
225 if ( frooting_depth_inches > 0.0_c_float ) then
226 ftemp_awc = ftemp_awc / frooting_depth_inches ! divide by total rooting depth to obtain weighted average
227 else
228 ftemp_awc = 0.0_c_float
229 endif
230
231 ! table values are in/in; multiply by 12 in/ft to return AWC in inches/foot
232 available_water_content(iindex_x, iindex_y) = ftemp_awc * 12.0_c_float
233
234 enddo
235
236 enddo
237
238
239! Original HWB code...
240
241! c........compute area-weighted soil-moisture storage capacity and account for
242! c depth-varying AWC
243! smca(i,k)=0.
244! do 420 j=1,nseq(i)
245! do 400 l=1,nlay(i,j)
246! if(z.ge.zt(i,j,l).and.z.le.zb(i,j,l))then
247! c...........bottom of root zone is within current layer
248! smca(i,k)=smca(i,k)+pct(i,j,l)*awc(i,j,l)*(z-zt(i,j,l))
249! elseif(z.gt.zb(i,j,l).and.l.eq.nlay(i,j))then
250! c...........bottom of root zone is below current layer, which is the
251! c bottom layer; extrapolate bottom layer down to root depth
252! smca(i,k)=smca(i,k)+pct(i,j,l)*awc(i,j,l)*(z-zt(i,j,l))
253! elseif(z.gt.zb(i,j,l).and.l.lt.nlay(i,j))then
254! c...........bottom of root zone is below current layer, which is not the
255! c bottom layer; include entire current layer
256! smca(i,k)=smca(i,k)+pct(i,j,l)*awc(i,j,l)*
257! 1 (zb(i,j,l)-zt(i,j,l))
258! c...........exit if bottom of root zone is above current layer
259! elseif(z.lt.zt(i,j,l))then
260! goto 440
261! endif
262! 400 continue
263! 420 continue
264! 440 continue
265
266
267
268
269 end subroutine awc_depth_integrated_read
270
271!--------------------------------------------------------------------------------------------------
272
273 subroutine awc_depth_integrated_initialize( lActive, fAWC, iSoils_Code )
274
275 logical (c_bool), intent(in) :: lactive(:,:)
276 real (c_float), intent(inout) :: fawc(:)
277 integer (c_int), intent(inout) :: isoils_code(:)
278
279 isoils_code = pack( psoils_code_grid%pGrdBase%iData, lactive )
280
281 fawc = pack( available_water_content, lactive )
282
284
285end module awc__depth_integrated
Populate the available water content by reading in and depth-averaging soil available water contents ...
subroutine, public awc_depth_integrated_initialize(lactive, fawc, isoils_code)
type(data_catalog_entry_t), pointer psoils_code_grid
subroutine, public awc_depth_integrated_read(frooting_depth)
real(c_float), dimension(:,:), allocatable, public available_water_content
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.
type(parameters_t), public params