-
Notifications
You must be signed in to change notification settings - Fork 92
/
Copy pathFatesLitterMod.F90
372 lines (282 loc) · 14.8 KB
/
FatesLitterMod.F90
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
module FatesLitterMod
! -------------------------------------------------------------------------------------
! This module contains methods and type definitions for all things litter.
! "litter" is used here in the broadest sense. It means all organic material
! that is no longer associated with a live plant.
!
! This encompasses: 1) "Coarse Woody Debris"
! 2) fine materials leaves, roots etc
! (sometimes exclusively refered to as litter)
! 3) Reproductive materials (seeds, nuts, fruits)
!
! Important point: THESE POOLS DO NOT CONTAIN DECOMPOSING MATTER !!!!!
!
! Continued: These litter pools will fragment, and then be passed to a
! soil-biogeochemical model (NOT FATES) to handle decomposition.
! -------------------------------------------------------------------------------------
! To-do:
! 1) Add the state integration step
! 2) Evaluate how we are handling disturbance
! 3) Add root fraction variable to each cohort?
! 4) Tracking site level mass balances, where should the new litter structure
! help in tracking that sort of thing?
! 5) Add a routine that performs all of the site-level mass balance
! integrations from daily sources?
! 6) Add check in the initialization sequence to make sure that the
! first element is carbon12_element, and carbon12_element is 1
! 7) In SFMain, make the indexing consistent with Jackie's changes
! 8) In CWD_IN, add the flux diagnostics, then remove the
! patch level rate in the history code
! 9) Add litter_flux_output to the flux_diags, add it to history
! 10) Add termination fluxes to the flux_diags array as well
! 11) re-evaluate the removed FATES_BGC_Carbon_Balancecheck
! re-write per its original intent
use FatesConstantsMod, only : r8 => fates_r8
use FatesConstantsMod, only : i4 => fates_int
use FatesConstantsMod, only : nearzero
use FatesConstantsMod, only : calloc_abs_error
use FatesConstantsMod, only : fates_unset_r8
use FatesGlobals , only : endrun => fates_endrun
use FatesGlobals , only : fates_log
use shr_log_mod , only : errMsg => shr_log_errMsg
implicit none
private
integer, public, parameter :: ncwd = 4 ! number of coarse woody debris pools
! (twig,s branch,l branch, trunk)
type, public :: litter_type
! This object is allocated for each element (C, N, P, etc) that we wish to track.
integer :: element_id ! This element ID should
! be associated with the element
! types listed in parteh/PRTGenericMod.F90
! Prognostic variables (litter and coarse woody debris)
real(r8) :: ag_cwd(ncwd) ! above ground coarse wood debris (cwd) [kg/m2]
real(r8),allocatable :: bg_cwd(:,:) ! below ground coarse wood debris (cwd x soil) [kg/m2]
real(r8),allocatable :: leaf_fines(:) ! above ground leaf litter (pft) [kg/m2]
real(r8),allocatable :: root_fines(:,:) ! below ground fine root litter (pft x soil) [kg/m2]
real(r8),allocatable :: seed(:) ! the seed pool (viable) (pft) [kg/m2]
real(r8),allocatable :: seed_germ(:) ! the germinated seed pool (pft) [kg/m2]
! Fluxes in - dying trees / seed rain (does not include disturbance fluxes)
real(r8) :: ag_cwd_in(ncwd) ! kg/m2/day
real(r8),allocatable :: bg_cwd_in(:,:) ! kg/m2/day
real(r8),allocatable :: leaf_fines_in(:) ! kg/m2/day
real(r8),allocatable :: root_fines_in(:,:) ! kg/m2/day
real(r8),allocatable :: seed_in_local(:) ! kg/m2/day (from local sources)
real(r8),allocatable :: seed_in_extern(:) ! kg/m2/day (from outside cell)
! Fluxes out - fragmentation
real(r8) :: ag_cwd_frag(ncwd) ! kg/m2/day
real(r8),allocatable :: bg_cwd_frag(:,:) ! kg/m2/day
real(r8),allocatable :: leaf_fines_frag(:) ! kg/m2/day
real(r8),allocatable :: root_fines_frag(:,:) ! kg/m2/day
! Fluxes out from burning are not tracked here because this process changes
! the size of the patch as well, and the unit fluxes that would be tracked
! here are convoluted
! Flux (in/out ... transfer) of seeds
real(r8), allocatable :: seed_decay(:) ! decay of viable seeds to litter [kg/m2/day]
real(r8), allocatable :: seed_germ_decay(:) ! decay of germinated seeds to litter [kg/m2/day]
real(r8), allocatable :: seed_germ_in(:) ! flux from viable to germinated seed [kg/m2/day]
contains
procedure,non_overridable :: InitAllocate
procedure,non_overridable :: DeallocateLitt
procedure,non_overridable :: InitConditions
procedure,non_overridable :: FuseLitter
procedure,non_overridable :: CopyLitter
procedure,non_overridable :: ZeroFlux
end type litter_type
! Part 3: Public extended types
character(len=*), parameter, private :: sourcefile = __FILE__
contains
subroutine FuseLitter(this,self_area,donor_area,donor_litt)
class(litter_type) :: this
real(r8),intent(in) :: self_area
real(r8),intent(in) :: donor_area
type(litter_type),intent(in) :: donor_litt
! locals
integer :: nlevsoil ! number of soil layers
integer :: c ! cwd index
integer :: pft ! pft index
integer :: ilyr ! soil layer index
integer :: npft ! number of PFTs
real(r8) :: self_weight
real(r8) :: donor_weight
nlevsoil = size(this%bg_cwd,dim=2)
npft = size(this%leaf_fines,dim=1)
self_weight = self_area /(donor_area+self_area)
donor_weight = 1._r8 - self_weight
do c=1,ncwd
this%ag_cwd(c) = this%ag_cwd(c) *self_weight + &
donor_litt%ag_cwd(c) * donor_weight
this%ag_cwd_in(c) = this%ag_cwd_in(c) *self_weight + &
donor_litt%ag_cwd_in(c) * donor_weight
this%ag_cwd_frag(c) = this%ag_cwd_frag(c) *self_weight + &
donor_litt%ag_cwd_frag(c) * donor_weight
do ilyr = 1,nlevsoil
this%bg_cwd(c,ilyr) = this%bg_cwd(c,ilyr) * self_weight + &
donor_litt%bg_cwd(c,ilyr) * donor_weight
this%bg_cwd_in(c,ilyr) = this%bg_cwd_in(c,ilyr) * self_weight + &
donor_litt%bg_cwd_in(c,ilyr) * donor_weight
this%bg_cwd_frag(c,ilyr) = this%bg_cwd_frag(c,ilyr) * self_weight + &
donor_litt%bg_cwd_frag(c,ilyr) * donor_weight
end do
end do
do pft=1,npft
this%leaf_fines(pft) = this%leaf_fines(pft) * self_weight + &
donor_litt%leaf_fines(pft) * donor_weight
this%seed(pft) = this%seed(pft) * self_weight + &
donor_litt%seed(pft) * donor_weight
this%seed_germ(pft) = this%seed_germ(pft) * self_weight + &
donor_litt%seed_germ(pft) * donor_weight
this%leaf_fines_in(pft) = this%leaf_fines_in(pft) * self_weight + &
donor_litt%leaf_fines_in(pft) * donor_weight
this%seed_in_local(pft) = this%seed_in_local(pft) * self_weight + &
donor_litt%seed_in_local(pft) * donor_weight
this%seed_in_extern(pft) = this%seed_in_extern(pft) * self_weight + &
donor_litt%seed_in_extern(pft) * donor_weight
this%leaf_fines_frag(pft) = this%leaf_fines_frag(pft) * self_weight + &
donor_litt%leaf_fines_frag(pft) * donor_weight
this%seed_decay(pft) = this%seed_decay(pft) * self_weight + &
donor_litt%seed_decay(pft) * donor_weight
this%seed_germ_decay(pft) = this%seed_germ_decay(pft) * self_weight + &
donor_litt%seed_germ_decay(pft) * donor_weight
this%seed_germ_in(pft) = this%seed_germ_in(pft) * self_weight + &
donor_litt%seed_germ_in(pft) * donor_weight
do ilyr=1,nlevsoil
this%root_fines(pft,ilyr) = this%root_fines(pft,ilyr) * self_weight + &
donor_litt%root_fines(pft,ilyr) * donor_weight
this%root_fines_in(pft,ilyr) = this%root_fines_in(pft,ilyr) * self_weight + &
donor_litt%root_fines_in(pft,ilyr) * donor_weight
this%root_fines_frag(pft,ilyr) = this%root_fines_frag(pft,ilyr) * self_weight + &
donor_litt%root_fines_frag(pft,ilyr) * donor_weight
end do
end do
return
end subroutine FuseLitter
! =====================================================================================
subroutine CopyLitter(this,donor_litt)
! This might not need to ever be called. When a new patch is created
! from disturbance, litter initialization is handled elsewhere (EDPatchDynamics)
class(litter_type) :: this
type(litter_type),intent(in) :: donor_litt
this%ag_cwd(:) = donor_litt%ag_cwd(:)
this%ag_cwd_in(:) = donor_litt%ag_cwd_in(:)
this%ag_cwd_frag(:) = donor_litt%ag_cwd_frag(:)
this%bg_cwd(:,:) = donor_litt%bg_cwd(:,:)
this%bg_cwd_in(:,:) = donor_litt%bg_cwd_in(:,:)
this%bg_cwd_frag(:,:) = donor_litt%bg_cwd_frag(:,:)
this%leaf_fines(:) = donor_litt%leaf_fines(:)
this%seed(:) = donor_litt%seed(:)
this%seed_germ(:) = donor_litt%seed_germ(:)
this%leaf_fines_in(:) = donor_litt%leaf_fines_in(:)
this%seed_in_local(:) = donor_litt%seed_in_local(:)
this%seed_in_extern(:) = donor_litt%seed_in_extern(:)
this%leaf_fines_frag(:) = donor_litt%leaf_fines_frag(:)
this%seed_decay(:) = donor_litt%seed_decay(:)
this%seed_germ_decay(:) = donor_litt%seed_germ_decay(:)
this%seed_germ_in(:) = donor_litt%seed_germ_in(:)
this%root_fines(:,:) = donor_litt%root_fines(:,:)
this%root_fines_in(:,:) = donor_litt%root_fines_in(:,:)
this%root_fines_frag(:,:) = donor_litt%root_fines_frag(:,:)
return
end subroutine CopyLitter
! =====================================================================================
subroutine InitAllocate(this,numpft,numlevsoil)
class(litter_type) :: this
integer,intent(in) :: numpft ! number of plant functional types
integer,intent(in) :: numlevsoil ! number of soil layers
allocate(this%bg_cwd(ncwd,numlevsoil))
allocate(this%leaf_fines(numpft))
allocate(this%root_fines(numpft,numlevsoil))
allocate(this%seed(numpft))
allocate(this%seed_germ(numpft))
allocate(this%bg_cwd_in(ncwd,numlevsoil))
allocate(this%leaf_fines_in(numpft))
allocate(this%root_fines_in(numpft,numlevsoil))
allocate(this%seed_in_local(numpft))
allocate(this%seed_in_extern(numpft))
allocate(this%bg_cwd_frag(ncwd,numlevsoil))
allocate(this%leaf_fines_frag(numpft))
allocate(this%root_fines_frag(numpft,numlevsoil))
allocate(this%seed_germ_in(numpft))
allocate(this%seed_germ_decay(numpft))
allocate(this%seed_decay(numpft))
! Initialize everything to a nonsense flag
this%ag_cwd(:) = fates_unset_r8
this%bg_cwd(:,:) = fates_unset_r8
this%leaf_fines(:) = fates_unset_r8
this%root_fines(:,:) = fates_unset_r8
this%seed(:) = fates_unset_r8
this%seed_germ(:) = fates_unset_r8
this%ag_cwd_in(:) = fates_unset_r8
this%bg_cwd_in(:,:) = fates_unset_r8
this%leaf_fines_in(:) = fates_unset_r8
this%root_fines_in(:,:) = fates_unset_r8
this%seed_in_local(:) = fates_unset_r8
this%seed_in_extern(:) = fates_unset_r8
this%ag_cwd_frag(:) = fates_unset_r8
this%bg_cwd_frag(:,:) = fates_unset_r8
this%leaf_fines_frag(:) = fates_unset_r8
this%root_fines_frag(:,:) = fates_unset_r8
this%seed_decay(:) = fates_unset_r8
this%seed_germ_decay(:) = fates_unset_r8
this%seed_germ_in(:) = fates_unset_r8
return
end subroutine InitAllocate
! =====================================================================================
subroutine InitConditions(this, &
init_leaf_fines, &
init_root_fines, &
init_ag_cwd, &
init_bg_cwd, &
init_seed)
class(litter_type) :: this
real(r8),intent(in) :: init_leaf_fines
real(r8),intent(in) :: init_root_fines
real(r8),intent(in) :: init_ag_cwd
real(r8),intent(in) :: init_bg_cwd
real(r8),intent(in) :: init_seed
this%ag_cwd(:) = init_leaf_fines
this%bg_cwd(:,:) = init_root_fines
this%leaf_fines(:) = init_ag_cwd
this%root_fines(:,:) = init_bg_cwd
this%seed(:) = init_seed
return
end subroutine InitConditions
! =====================================================================================
subroutine DeallocateLitt(this)
class(litter_type) :: this
deallocate(this%bg_cwd)
deallocate(this%leaf_fines)
deallocate(this%root_fines)
deallocate(this%seed)
deallocate(this%seed_germ)
deallocate(this%bg_cwd_in)
deallocate(this%leaf_fines_in)
deallocate(this%root_fines_in)
deallocate(this%seed_in_local)
deallocate(this%seed_in_extern)
deallocate(this%bg_cwd_frag)
deallocate(this%leaf_fines_frag)
deallocate(this%root_fines_frag)
deallocate(this%seed_decay)
deallocate(this%seed_germ_decay)
deallocate(this%seed_germ_in)
return
end subroutine DeallocateLitt
! =====================================================================================
subroutine ZeroFlux(this)
class(litter_type) :: this
this%ag_cwd_in(:) = 0._r8
this%bg_cwd_in(:,:) = 0._r8
this%leaf_fines_in(:) = 0._r8
this%root_fines_in(:,:) = 0._r8
this%seed_in_local(:) = 0._r8
this%seed_in_extern(:) = 0._r8
this%ag_cwd_frag(:) = 0._r8
this%bg_cwd_frag(:,:) = 0._r8
this%leaf_fines_frag(:) = 0._r8
this%root_fines_frag(:,:) = 0._r8
this%seed_germ_in(:) = 0._r8
this%seed_decay(:) = 0._r8
this%seed_germ_decay(:) = 0._r8
return
end subroutine ZeroFlux
end module FatesLitterMod