source: tags/ORCHIDEE_1_9_6/ORCHIDEE/src_stomate/stomate_vmax.f90 @ 880

Last change on this file since 880 was 720, checked in by didier.solyga, 12 years ago

Add svn headers for all modules. Improve documentation of the parameters. Replace two values by the corresponding parameters.

  • Property svn:keywords set to HeadURL Date Author Revision
File size: 7.2 KB
Line 
1! calculates the leaf efficiency
2!
3!< $HeadURL$
4!< $Date$
5!< $Author$
6!< $Revision$
7! IPSL (2006)
8!  This software is governed by the CeCILL licence see ORCHIDEE/ORCHIDEE_CeCILL.LIC
9!
10MODULE stomate_vmax
11
12  ! modules used:
13
14  USE ioipsl
15  USE stomate_data
16  USE constantes
17  USE pft_parameters
18
19  IMPLICIT NONE
20
21  ! private & public routines
22
23  PRIVATE
24  PUBLIC vmax, vmax_clear
25
26  ! first call
27  LOGICAL, SAVE                                              :: firstcall = .TRUE.
28
29CONTAINS
30
31  SUBROUTINE vmax_clear
32    firstcall=.TRUE.
33  END SUBROUTINE vmax_clear
34
35  SUBROUTINE vmax (npts, dt, &
36       leaf_age, leaf_frac, &
37       vcmax, vjmax)
38
39    !
40    ! 0 declarations
41    !
42
43    ! 0.1 input
44
45    ! Domain size
46    INTEGER(i_std), INTENT(in)                                        :: npts
47    ! time step of Stomate in days
48    REAL(r_std), INTENT(in)                                     :: dt
49
50    ! 0.2 modified fields
51
52    ! leaf age (days)
53    REAL(r_std), DIMENSION(npts,nvm,nleafages), INTENT(inout)  :: leaf_age
54    ! fraction of leaves in leaf age class
55    REAL(r_std), DIMENSION(npts,nvm,nleafages), INTENT(inout)  :: leaf_frac
56
57    ! 0.3 output
58
59    ! Maximum rate of carboxylation
60    REAL(r_std), DIMENSION(npts,nvm), INTENT(out)              :: vcmax
61    ! Maximum rate of RUbp regeneration
62    REAL(r_std), DIMENSION(npts,nvm), INTENT(out)              :: vjmax
63
64    ! 0.4 local
65
66    ! leaf efficiency (vcmax/vcmax_opt)
67    REAL(r_std), DIMENSION(npts)                                :: leaf_efficiency
68    ! change of fraction of leaves in age class
69    REAL(r_std), DIMENSION(npts,nvm,nleafages)                 :: d_leaf_frac
70    ! new leaf age (d)
71    REAL(r_std), DIMENSION(npts,nleafages)                      :: leaf_age_new
72    ! sum of leaf age fractions, for normalization
73    REAL(r_std), DIMENSION(npts)                                :: sumfrac
74    ! relative leaf age (age/critical age)
75    REAL(r_std), DIMENSION(npts)                                :: rel_age
76    ! Index
77    INTEGER(i_std)                                              :: j,m
78
79    ! =========================================================================
80
81    IF (bavard.GE.3) WRITE(numout,*) 'Entering vmax'
82
83    !
84    ! 1 Initialization
85    !
86
87    !
88    ! 1.1 first call: info about flags and parameters.
89    !
90
91    IF ( firstcall ) THEN
92
93       WRITE(numout,*) 'vmax:'
94
95       WRITE(numout,*) '   > offset (minimum vcmax/vmax_opt):' , vmax_offset
96       WRITE(numout,*) '   > relative leaf age at which vmax attains vcmax_opt:', leafage_firstmax
97       WRITE(numout,*) '   > relative leaf age at which vmax falls below vcmax_opt:', leafage_lastmax
98       WRITE(numout,*) '   > relative leaf age at which vmax attains its minimum:', leafage_old
99
100       firstcall = .FALSE.
101
102    ENDIF
103
104    !
105    ! 1.2 initialize output
106    !
107
108    vcmax(:,:) = zero
109    vjmax(:,:) = zero
110
111    !
112    ! 2 leaf age: general increase and turnover between age classes.
113    !
114
115    !
116    ! 2.1 increase leaf age
117    !
118
119    DO m = 1, nleafages
120
121       DO j = 2,nvm
122          WHERE ( leaf_frac(:,j,m) .GT. min_stomate )
123
124             leaf_age(:,j,m) = leaf_age(:,j,m) + dt
125             
126          ENDWHERE
127       ENDDO
128
129    ENDDO
130
131    !
132    ! 2.2 turnover between leaf age classes
133    !     d_leaf_frac(:,:,m) = what leaves m-1 and goes into m
134    !
135
136    DO j = 2,nvm
137
138       ! 2.2.1 fluxes
139
140       ! nothing goes into first age class
141       d_leaf_frac(:,j,1) = zero
142
143       ! from m-1 to m
144       DO m = 2, nleafages 
145
146          d_leaf_frac(:,j,m) = leaf_frac(:,j,m-1) * dt/leaf_timecst(j)
147
148       ENDDO
149
150       ! 2.2.2 new leaf age in class
151       !       new age = ( old age * old fraction + fractional increase * age of source ) /
152       !                 new fraction
153
154       leaf_age_new(:,:) = zero
155
156       DO m = 2, nleafages-1
157          !      DO m=2, nleafages
158
159          WHERE ( d_leaf_frac(:,j,m) .GT. min_stomate )
160
161             leaf_age_new(:,m) = ( ( (leaf_frac(:,j,m)- d_leaf_frac(:,j,m+1)) * leaf_age(:,j,m) )  + &
162                  ( d_leaf_frac(:,j,m) * leaf_age(:,j,m-1) ) ) / &
163                  ( leaf_frac(:,j,m) + d_leaf_frac(:,j,m)- d_leaf_frac(:,j,m+1) )
164
165             !           leaf_age_new(:,m) = ( ( leaf_frac(:,j,m) * leaf_age(:,j,m) )  + &
166             !                                ( d_leaf_frac(:,j,m) * leaf_age(:,j,m-1) ) ) / &
167             !                              ( leaf_frac(:,j,m) + d_leaf_frac(:,j,m) )
168
169          ENDWHERE
170
171       ENDDO       ! Loop over age classes
172
173       WHERE ( d_leaf_frac(:,j,nleafages) .GT. min_stomate )
174
175          leaf_age_new(:,nleafages) = ( ( leaf_frac(:,j,nleafages) * leaf_age(:,j,nleafages) )  + &
176               ( d_leaf_frac(:,j,nleafages) * leaf_age(:,j,nleafages-1) ) ) / &
177               ( leaf_frac(:,j,nleafages) + d_leaf_frac(:,j,nleafages) )
178
179       ENDWHERE
180
181       DO m = 2, nleafages
182
183          WHERE ( d_leaf_frac(:,j,m) .GT. min_stomate )
184
185             leaf_age(:,j,m) = leaf_age_new(:,m)
186
187          ENDWHERE
188
189       ENDDO       ! Loop over age classes
190
191       ! 2.2.3 calculate new fraction
192
193       DO m = 2, nleafages
194
195          ! where the change comes from
196          leaf_frac(:,j,m-1) = leaf_frac(:,j,m-1) - d_leaf_frac(:,j,m)
197
198          ! where it goes to
199          leaf_frac(:,j,m) = leaf_frac(:,j,m) + d_leaf_frac(:,j,m)
200
201       ENDDO
202
203       ! 2.2.4 renormalize fractions in order to prevent accumulation
204       !       of numerical errors
205
206       ! correct small negative values
207
208       DO m = 1, nleafages
209          leaf_frac(:,j,m) = MAX( zero, leaf_frac(:,j,m) )
210       ENDDO
211
212       ! total of fractions, should be very close to one where there is leaf mass
213
214       sumfrac(:) = zero
215
216       DO m = 1, nleafages
217
218          sumfrac(:) = sumfrac(:) + leaf_frac(:,j,m)
219
220       ENDDO
221
222       ! normalize
223
224       DO m = 1, nleafages
225
226          WHERE ( sumfrac(:) .GT. min_stomate )
227
228             leaf_frac(:,j,m) = leaf_frac(:,j,m) / sumfrac(:) 
229
230          ELSEWHERE
231
232             leaf_frac(:,j,m) = zero
233
234          ENDWHERE
235
236       ENDDO
237
238    ENDDO         ! Loop over PFTs
239
240    !
241    ! 3 calculate vmax as a function of the age
242    !
243
244    DO j = 2,nvm
245
246       vcmax(:,j) = zero
247       vjmax(:,j) = zero
248
249       ! sum up over the different age classes
250
251       DO m = 1, nleafages
252
253          !
254          ! 3.1 efficiency in each of the age classes
255          !     increases from 0 to 1 at the beginning (rel_age < leafage_firstmax), stays 1
256          !     until rel_age = leafage_lastmax, then decreases to vmax_offset at
257          !     rel_age = leafage_old, then stays at vmax_offset.
258          !
259
260          rel_age(:) = leaf_age(:,j,m) / leafagecrit(j)
261
262          leaf_efficiency(:) = MAX( vmax_offset, MIN( un, &
263               vmax_offset + (un - vmax_offset) * rel_age(:) / leafage_firstmax, &
264               un - (un - vmax_offset) * ( rel_age(:) - leafage_lastmax ) / &
265               ( leafage_old - leafage_lastmax ) ) )
266
267          !
268          ! 3.2 add to mean vmax
269          !
270
271          vcmax(:,j) = vcmax(:,j) + vcmax_opt(j) * leaf_efficiency(:) * leaf_frac(:,j,m)
272          vjmax(:,j) = vjmax(:,j) + vjmax_opt(j) * leaf_efficiency(:) * leaf_frac(:,j,m)
273
274       ENDDO     ! loop over age classes
275
276    ENDDO       ! loop over PFTs
277
278    IF (bavard.GE.4) WRITE(numout,*) 'Leaving vmax'
279
280  END SUBROUTINE vmax
281
282END MODULE stomate_vmax
Note: See TracBrowser for help on using the repository browser.