SURFEX v8.1
General documentation of Surfex
e_budget_meb.F90
Go to the documentation of this file.
1 !SFX_LIC Copyright 1994-2014 CNRS, Meteo-France and Universite Paul Sabatier
2 !SFX_LIC This is part of the SURFEX software governed by the CeCILL-C licence
3 !SFX_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt
4 !SFX_LIC for details. version 1.
5 ! ##########################################################################
6  SUBROUTINE e_budget_meb(IO, KK, PK, PEK, DK, DEK, DMK, &
7  PTSTEP, PLTT, PPS, PCT, PTDEEP_A, PD_G, PSOILCONDZ, &
8  PSOILHCAPZ, PSNOWRHO, PSNOWCONDZ, PSNOWHCAPZ, PTAU_N, &
9  PLWNET_V_DTV, PLWNET_V_DTG, PLWNET_V_DTN, &
10  PLWNET_G_DTV, PLWNET_G_DTG, PLWNET_G_DTN, &
11  PLWNET_N_DTV, PLWNET_N_DTG, PLWNET_N_DTN, &
12  PPEW_A_COEF, PPEW_B_COEF, PPET_A_COEF, &
13  PPEQ_A_COEF, PPET_B_COEF, PPEQ_B_COEF, &
14  PTHRMA_TA, PTHRMB_TA, PTHRMA_TC, PTHRMB_TC, &
15  PTHRMA_TG, PTHRMB_TG, PTHRMA_TV, PTHRMB_TV, &
16  PTHRMA_TN, PTHRMB_TN, PQSAT_G, PQSAT_V, &
17  PQSATI_N, PPSNA, PPSNCV, PCHEATV, PCHEATG, &
18  PCHEATN, PLEG_DELTA, PLEGI_DELTA, PHUGI, &
19  PHVG, PHVN, PFROZEN1, PFLXC_C_A, PFLXC_G_C, &
20  PFLXC_VG_C, PFLXC_VN_C, PFLXC_N_C, PFLXC_N_A,&
21  PFLXC_MOM, PTG, PSNOWLIQ, PFLXC_V_C, PHVGS, PHVNS, &
22  PDQSAT_G, PDQSAT_V, PDQSATI_N, PTA_IC, &
23  PQA_IC, PUSTAR2_IC, PVMOD, PDELTAT_G, &
24  PDELTAT_V, PDELTAT_N, PGRNDFLUX, PDEEP_FLUX, &
25  PDELHEATV_SFC, PDELHEATG_SFC, PDELHEATG )
26 ! ##########################################################################
27 !
28 !!**** *E_BUDGET*
29 !!
30 !! PURPOSE
31 !! -------
32 !
33 ! Calculates the implicit simulataneous solution of multiple surface
34 ! energy budgets (understory vegetation-soil composite, vegetation canopy
35 ! and explicit snowpack) and sub-surface soil temperatures. Canopy
36 ! air space temperature and specific humidities are also diagnosed.
37 ! Fully implicit coupling with the atmosphere allowed.
38 ! Note that a 'test' snow temperature is computed herein which is just
39 ! use to compute the surface fluxes. These fluxes are then used within
40 ! the snow scheme as an upper boundary condition to compute the snow
41 ! temperatures. In theory, they should be very close, but this method is
42 ! done to ensure a high level of energy conservation.
43 !
44 !
45 !!** METHOD
46 !! ------
47 !
48 ! 1- compute coefficients for each energy budget
49 ! 2- solve the equations for snow, vegetation canopy and soil-understory
50 ! vegetation composite
51 ! 3- solve soil T profile
52 ! 4- diagnose canopy air space variables, and lowest level atmospheric
53 ! state variable values at t+dt
54 !
55 !! EXTERNAL
56 !! --------
57 !!
58 !! none
59 !!
60 !! IMPLICIT ARGUMENTS
61 !! ------------------
62 !!
63 !!
64 !!
65 !! REFERENCE
66 !! ---------
67 !!
68 !! Noilhan and Planton (1989)
69 !! Belair (1995)
70 !! * to be done * (2011)
71 !!
72 !! AUTHOR
73 !! ------
74 !!
75 !! A. Boone * CNRM-GAME, Meteo-France *
76 !! P. Samuelsson * SMHI *
77 !! S. Gollvik * SMHI *
78 !!
79 !! MODIFICATIONS
80 !! -------------
81 !! Original 22/01/11
82 !! 10/10/14 (A. Boone) Removed understory vegetation
83 !!
84 !-------------------------------------------------------------------------------
85 !
86 !* 0. DECLARATIONS
87 ! ------------
88 !
91 USE modd_diag_n, ONLY : diag_t
94 !
95 USE modd_csts, ONLY : xlvtt, xlstt, xtt, xcpd, xcpv, xcl, &
96  xday, xpi, xlmtt, xrholw
97 USE modd_surf_atm, ONLY : lcpl_arp
98 USE modd_surf_par, ONLY : xundef
99 USE modd_snow_metamo, ONLY : xsnowdzmin
100 !
101 USE mode_thermos
102 USE mode_meb, ONLY : sfc_heatcap_veg
103 USE mode_snow3l, ONLY : snow3lhold
104 !
105 USE modi_tridiag_ground_rm_coefs
106 USE modi_tridiag_ground_rm_soln
107 !
108 USE yomhook ,ONLY : lhook, dr_hook
109 USE parkind1 ,ONLY : jprb
110 !
111 IMPLICIT NONE
112 !
113 !* 0.1 declarations of arguments
114 !
115 TYPE(isba_options_t), INTENT(INOUT) :: IO
116 TYPE(isba_k_t), INTENT(INOUT) :: KK
117 TYPE(isba_p_t), INTENT(INOUT) :: PK
118 TYPE(isba_pe_t), INTENT(INOUT) :: PEK
119 TYPE(diag_t), INTENT(INOUT) :: DK
120 TYPE(diag_evap_isba_t), INTENT(INOUT) :: DEK
121 TYPE(diag_misc_isba_t), INTENT(INOUT) :: DMK
122 !
123 REAL, INTENT(IN) :: PTSTEP
124 ! PTSTEP = timestep of the integration (s)
125 !
126 REAL, DIMENSION(:), INTENT(IN) :: PCT
127 ! PCT = surface understory or composite thermal inertia (m2 K J-1)
128 !
129 REAL, DIMENSION(:), INTENT(IN) :: PTDEEP_A
130 ! PTDEEP_A = Deep soil temperature
131 ! coefficient depending on flux
132 ! Tdeep = IP%XTDEEP + PTDEEP_A * PDEEP_FLUX
133 ! (with PDEEP_FLUX in W/m2)
134 !
135 REAL, DIMENSION(:), INTENT(IN) :: PPS
136 ! PPS = surface pressure (Pa)
137 !
138 REAL, DIMENSION(:,:), INTENT(IN) :: PD_G, PSOILCONDZ, PSOILHCAPZ
139 ! PD_G = soil layer depth (m)
140 ! PSOILCONDZ = soil thermal conductivity (W m-1 K-1)
141 ! PSOILHCAPZ = soil heat capacity (J m-3 K-1)
142 !
143 REAL, DIMENSION(:,:), INTENT(IN) :: PSNOWCONDZ, PSNOWHCAPZ, PSNOWRHO
144 ! PSNOWCONDZ = snow thermal conductivity (W m-1 K-1)
145 ! PSNOWHCAPZ = snow heat capacity (J m-3 K-1)
146 ! PSNOWRHO = snow layer density (kg/m3)
147 !
148 REAL, DIMENSION(:,:), INTENT(IN) :: PTAU_N
149 ! PTAU_N = shortwave radiation transmission through (at the base of)
150 ! each snow layer. Implicitly PTAU_N(0) = 1 (-)
151 ! It decreases with depth to zero somewhere in a deep snowpack,
152 ! but can be above 0 at snowpack base for shallow snow, then
153 ! it is presumed to go into the uppermost soil layer.
154 !
155 REAL, DIMENSION(:), INTENT(IN) :: PLWNET_V_DTV, PLWNET_V_DTG, PLWNET_V_DTN
156 ! PLWNET_V_DTV, PLWNET_V_DTG, PLWNET_V_DTN = Vegetation canopy net LW radiation
157 ! derivatives w/r/t surface temperature(s) (W m-2 K-1)
158 !
159 REAL, DIMENSION(:), INTENT(IN) :: PLWNET_G_DTV, PLWNET_G_DTG, PLWNET_G_DTN
160 ! PLWNET_G_DTV, PLWNET_G_DTG, PLWNET_G_DTN = Understory-ground net LW radiation
161 ! derivatives w/r/t surface temperature(s) (W m-2 K-1)
162 !
163 REAL, DIMENSION(:), INTENT(IN) :: PLWNET_N_DTV, PLWNET_N_DTG, PLWNET_N_DTN
164 ! PLWNET_N_DTV, PLWNET_N_DTG, PLWNET_N_DTN = Ground-based snow net LW radiation
165 ! derivatives w/r/t surface temperature(s) (W m-2 K-1)
166 !
167 REAL, DIMENSION(:), INTENT(IN) :: PTHRMA_TA, PTHRMB_TA, PTHRMA_TC, PTHRMB_TC, &
168  PTHRMA_TG, PTHRMB_TG, PTHRMA_TV, PTHRMB_TV, PTHRMA_TN, PTHRMB_TN
169 ! PTHRMA_TA (J kg-1 K-1)
170 ! PTHRMB_TA = linear transform coefficinets for atmospheric
171 ! thermal variable for lowest atmospheric level. (J kg-1)
172 ! Transform T to dry static energy or enthalpy.
173 ! PTHRMA_TC (J kg-1 K-1)
174 ! PTHRMB_TC = linear transform coefficinets for atmospheric
175 ! thermal variable for canopy air (J kg-1)
176 ! Transform T to dry static energy or enthalpy.
177 ! PTHRMA_TG,V,N (J kg-1 K-1)
178 ! PTHRMB_TG,V,N = linear transform coefficinets for atmospheric
179 ! thermal variable for surfaces (G, V, and N) (J kg-1)
180 ! Transform T to dry static energy or enthalpy.
181 !
182 REAL, DIMENSION(:), INTENT(IN) :: PPET_A_COEF, PPEQ_A_COEF, PPET_B_COEF, PPEQ_B_COEF, &
183  PPEW_A_COEF, PPEW_B_COEF
184 ! PPEW_A_COEF = wind atmospheric coupling coefficient
185 ! PPEW_B_COEF = wind atmospheric coupling coefficient
186 ! PPET_A_COEF = A-air temperature atmospheric coupling coefficient
187 ! PPET_B_COEF = B-air temperature atmospheric coupling coefficient
188 ! PPEQ_A_COEF = A-air specific humidity atmospheric coupling coefficient
189 ! PPEQ_B_COEF = B-air specific humidity atmospheric coupling coefficient
190 !
191 REAL, DIMENSION(:), INTENT(IN) :: PQSAT_G, PQSAT_V, PQSATI_N
192 ! PQSAT_G = saturation specific humidity for understory surface (kg kg-1)
193 ! PQSAT_V = saturation specific humidity for the vegetation canopy (kg kg-1)
194 ! PQSATI_N = saturation specific humidity over ice for the snowpack (kg kg-1)
195 !
196 REAL, DIMENSION(:), INTENT(IN) :: PPSNA, PPSNCV
197 ! PPSN = fraction of snow on ground and understory vegetation (-)
198 ! PPSNA = fraction of vegetation canopy buried by ground-based snowpack (-)
199 ! PPSNCV = fraction of vegetation canopy covered by intercepted snow (-)
200 !
201 REAL, DIMENSION(:), INTENT(IN) :: PLEG_DELTA, PLEGI_DELTA, PHUGI, PHVG, PHVN, PFROZEN1
202 ! PHUGI = relative humidity of the frozen surface soil (-)
203 ! PHVG = Halstead coefficient of non-buried (snow) canopy vegetation (-)
204 ! PHVN = Halstead coefficient of paritally-buried (snow) canopy vegetation (-)
205 ! PLEG_DELTA = soil evaporation delta fn (-)
206 ! PLEGI_DELTA = soil sublimation delta fn (-)
207 ! PFROZEN1 = fraction of surface soil layer which is frozen (-)
208 !
209 REAL, DIMENSION(:), INTENT(IN) :: PFLXC_C_A, PFLXC_G_C, PFLXC_VG_C, PFLXC_VN_C, PFLXC_N_C, PFLXC_N_A, PFLXC_MOM
210 ! PFLXC_C_A = Flux form heat transfer coefficient: canopy air to atmosphere (kg m-2 s-1)
211 ! PFLXC_G_C = As above, but for : ground-understory to canopy air (kg m-2 s-1)
212 ! PFLXC_VG_C = As above, but for : non-snow buried canopy to canopy air (kg m-2 s-1)
213 ! PFLXC_VN_C = As above, but for : partially snow-buried canopy air to canopy
214 ! air (kg m-2 s-1)
215 ! PFLXC_N_C = As above, but for : ground-based snow to atmosphere (kg m-2 s-1)
216 ! PFLXC_N_A = As above, but for : ground-based snow to canopy air (kg m-2 s-1)
217 ! PFLXC_MOM = flux form drag transfer coefficient: canopy air to atmosphere (kg m-2 s-1)
218 !
219 REAL, DIMENSION(:), INTENT(IN) :: PLTT
220 ! PLTT = latent heat normalization factor (J kg-1)
221 !
222 REAL, DIMENSION(:,:), INTENT(INOUT):: PTG
223 ! PTG = Soil temperature profile (K)
224 !
225 REAL, DIMENSION(:,:), INTENT(INOUT):: PSNOWLIQ
226 ! PSNOWLIQ = Snow layer liquid water content (m)
227 !
228 REAL, DIMENSION(:), INTENT(OUT) :: PCHEATV, PCHEATG, PCHEATN
229 ! PCHEATV = Vegetation canopy *effective surface* heat capacity (J m-2 K-1)
230 ! PCHEATG = Understory-ground *effective surface* heat capacity (J m-2 K-1)
231 ! PCHEATN = Ground-based snow *effective surface* heat capacity (J m-2 K-1)
232 !
233 REAL, DIMENSION(:), INTENT(OUT) :: PDQSAT_G, PDQSAT_V, PDQSATI_N
234 ! PQSAT_G = saturation specific humidity derivative for understory
235 ! surface (kg kg-1 K-1)
236 ! PQSAT_V = saturation specific humidity derivative for the vegetation
237 ! canopy (kg kg-1 K-1)
238 ! PQSATI_N = saturation specific humidity derivative over ice for the
239 ! ground-based snowpack (kg kg-1 K-1)
240 !
241 REAL, DIMENSION(:), INTENT(OUT) :: PFLXC_V_C, PHVGS, PHVNS
242 ! PFLXC_V_C = Flux form heat transfer coefficient: total canopy (partially
243 ! snow-buried and non-buried parts) to canopy air (kg m-2 s-1)
244 ! PHVGS = Dimensionless pseudo humidity factor for computing vapor
245 ! fluxes from the non-buried part of the canopy to the canopy air (-)
246 ! PHVNS = Dimensionless pseudo humidity factor for computing vapor
247 ! fluxes from the partly-buried part of the canopy to the canopy air (-)
248 !
249 REAL, DIMENSION(:), INTENT(OUT) :: PTA_IC, PQA_IC, PUSTAR2_IC, PVMOD
250 ! PTA_IC = Near-ground air temperature (K)
251 ! PQA_IC = Near-ground air specific humidity (kg kg-1)
252 ! PUSTAR2_IC = Surface friction velocity squared (m2 s-2)
253 ! (modified if implicit coupling with
254 ! atmosphere used)
255 ! PVMOD = lowest level wind speed (m s-1)
256 !
257 REAL, DIMENSION(:), INTENT(OUT) :: PDELTAT_V, PDELTAT_N, PDELTAT_G
258 ! PDELTAT_V = Time change in vegetation canopy temperature (K)
259 ! PDELTAT_N = Time change in snowpack surface temperature (K)
260 ! PDELTAT_G = Time change in soil surface temperature (K)
261 !
262 REAL, DIMENSION(:), INTENT(OUT) :: PGRNDFLUX
263 ! PGRNDFLUX = Flux between snowpack base and ground surface (W m-2)
264 !
265 REAL, DIMENSION(:), INTENT(OUT) :: PDEEP_FLUX ! Heat flux at bottom of ISBA (W/m2)
266 !
267 REAL, DIMENSION(:), INTENT(OUT) :: PDELHEATV_SFC, PDELHEATG_SFC, PDELHEATG
268 ! PDELHEATV_SFC = change in heat storage of the vegetation canopy layer over the current time step (W m-2)
269 ! PDELHEATG_SFC = change in heat storage of the surface soil layer over the current time step (W m-2)
270 ! PDELHEATG = change in heat storage of the entire soil column over the current time step (W m-2)
271 !
272 !* 0.2 declarations of local variables
273 !
274 !
275 INTEGER :: JNSNOW, JNGRND, JNPTS, JJ, JK, JL
276 !
277 REAL, DIMENSION(SIZE(PPS)) :: ZHN, ZHS, ZHVS, ZHNS
278 !
279 REAL, DIMENSION(SIZE(PTG,1),SIZE(PTG,2)) :: ZTGO
280 !
281 REAL, DIMENSION(SIZE(DMK%XSNOWTEMP,1),SIZE(DMK%XSNOWTEMP,2)) :: ZTNO
282 !
283 REAL, DIMENSION(SIZE(PTG,1)) :: ZTVO
284 !
285 REAL, DIMENSION(SIZE(PPS)) :: ZPSNAG, ZWORK, ZFFF, ZGCOND1
286 !
287 REAL, DIMENSION(SIZE(PPS)) :: ZPET_A_COEF_P, ZPET_B_COEF_P, ZPET_C_COEF_P
288 !
289 REAL, DIMENSION(SIZE(PPS)) :: ZPEQ_A_COEF_P, ZPEQ_B_COEF_P, ZPEQ_C_COEF_P
290 !
291 REAL, DIMENSION(SIZE(PPS)) :: ZCOEFA_TC, ZCOEFB_TC, ZCOEFC_TC, ZCOEFD_TC, &
292  ZCOEFA_QC, ZCOEFB_QC, ZCOEFC_QC, ZCOEFD_QC
293 !
294 REAL, DIMENSION(SIZE(PPS)) :: ZBETA_V, ZALPHA_V, ZGAMMA_V, &
295  ZBETA_G, ZALPHA_G, ZGAMMA_G, &
296  ZBETA_N, ZALPHA_N, ZGAMMA_N, &
297  ZBETA_P_V, ZALPHA_P_V, ZBETA_P_N, ZALPHA_P_N
298 !
299 REAL, DIMENSION(SIZE(PPS)) :: ZRNET_NN, ZRNET_N_DTNN, ZRNET_N_DTGN, ZRNET_N_DTVN
300 !
301 REAL, DIMENSION(SIZE(PPS)) :: ZVMOD, ZUSTAR2, ZPSNA
302 !
303 REAL, DIMENSION(SIZE(PPS)) :: ZTCONDA_DELZ_G, ZTCONDA_DELZ_N, ZTCONDA_DELZ_NG
304 !
305 REAL, DIMENSION(SIZE(PTG,1),SIZE(PTG,2)) :: ZSOIL_COEF_A, ZSOIL_COEF_B
306 !
307 REAL, DIMENSION(SIZE(DMK%XSNOWDZ,1),SIZE(DMK%XSNOWDZ,2)):: ZSNOW_COEF_A, ZSNOW_COEF_B
308 !
309 REAL, DIMENSION(SIZE(DMK%XSNOWDZ,1),SIZE(DMK%XSNOWDZ,2)):: ZWHOLDMAX
310 !
311 REAL, DIMENSION(SIZE(PD_G,1),SIZE(PD_G,2)+SIZE(DMK%XSNOWDZ,2)) :: ZD, ZT, ZHCAPZ, ZCONDZ, &
312  ZCOEF_A, ZCOEF_B, ZSOURCE
313 !
314 REAL(KIND=JPRB) :: ZHOOK_HANDLE
315 !-------------------------------------------------------------------------------
316 !
317 REAL, PARAMETER :: ZERTOL = 1.0e-6 ! -
318 REAL, PARAMETER :: ZERTOL_FLX_C = 1.0e-12 ! -
319 !
320 !-------------------------------------------------------------------------------
321 !
322 !* 0. Initialization:
323 ! ---------------
324 !
325 IF (lhook) CALL dr_hook('E_BUDGET_MEB',0,zhook_handle)
326 !
327 ztgo(:,:) = ptg(:,:)
328 ztno(:,:) = dmk%XSNOWTEMP(:,:)
329 ztvo(:) = pek%XTV(:)
330 
331 ! To prevent possible numerical problems in the limit as psna==>1, we
332 ! limit the value for certain computations:
333 
334 zpsna(:) = min(1.0-zertol, ppsna(:))
335 
336 jnsnow = SIZE(dmk%XSNOWTEMP,2)
337 jngrnd = SIZE(ptg,2)
338 jnpts = SIZE(ptg,1)
339 
340 ! sub-surface / surface coupling coefficients:
341 
342 zsoil_coef_a(:,:) = 0.0
343 zsoil_coef_b(:,:) = 0.0
344 zsnow_coef_a(:,:) = 0.0
345 zsnow_coef_b(:,:) = 0.0
346 
347 !-------------------------------------------------------------------------------
348 !
349 !* 1. Some variables/coefficients needed for coupling or solution
350 ! -----------------------------------------------------------
351 ! - Effective Surface heat capacities for each energy budget (J m-2 K-1)
352 !
353 pcheatg(:) = 1/pct(:) ! understory soil/floodplain
354 !
355 pcheatv(:) = sfc_heatcap_veg(pek%XWRVN(:),pek%XWR(:),pek%XCV) ! vegetation canopy heat capacity
356 !
357 pcheatn(:) = psnowhcapz(:,1)*dmk%XSNOWDZ(:,1) ! snow surface layer
358 !
359 ! - Specific humidity derivatives (kg kg-1 K-1)
360 !
361 pdqsat_g(:) = dqsat(ztgo(:,1), pps(:),pqsat_g(:) )
362 pdqsat_v(:) = dqsat(ztvo(:), pps(:),pqsat_v(:) )
363 pdqsati_n(:) = dqsati(ztno(:,1), pps(:),pqsati_n(:) )
364 !
365 ! - Precipitation heating term for snowpack:
366 ! Rainfall renders it's heat to the snow when it enters
367 ! the snowpack:
368 ! NOTE: for now set to zero because we'd need to remove this heat from
369 ! the atmosphere to conserve energy. This can be done, but should
370 ! be tested within an atmos model first probably...
371 ! ALSO, water should include canopy drip etc....but again, conservation
372 ! would need to be carefully accounted for. So for now within MEB,
373 ! set to 0. But code within MEB and ES can accept this term, so
374 ! if this process is added at some point, it would be here.
375 ! Also, it is treated explicitly...this might also have to be changed
376 ! to implicit depending how this term is expressed. That would require
377 ! modification to this routine and flux routine: but retain it here for possible
378 ! future implementation.
379 !
380 dmk%XHPSNOW(:) = 0.0 ! W m-2
381 !
382 ! Snowmeltwater advection which can heat uppermost soil layer if below freezing.
383 ! NOTE this term is currently OFF for MEB since it would mean keeping meltwater
384 ! flux from previous timestep (since snow called *after* energy budget). Also,
385 ! the heat would need to be removed from snowpack to conserve energy (and currently
386 ! not done) so we turn off for now (set to 0), but retain it here for possible
387 ! future implementation.
388 !
389 dek%XMELTADV(:) = 0.0 ! W m-2
390 !
391 ! - Implicit wind speed at lowest atmospheric level for this patch:
392 !
393 zustar2(:) = (pflxc_mom(:)*ppew_b_coef(:))/ &
394  (1.0-pflxc_mom(:)*ppew_a_coef(:))
395 !
396 zvmod(:) = ppew_a_coef(:)*zustar2(:) + ppew_b_coef(:)
397 !
398 pvmod(:) = max(zvmod,0.)
399 !
400 WHERE (ppew_a_coef(:) /= 0.)
401  zustar2(:) = max(0., ( pvmod(:) - ppew_b_coef(:) ) / ppew_a_coef(:) )
402 END WHERE
403 !
404 pustar2_ic(:)= zustar2(:)
405 !
406 ! NOTE: put in new option HIMPLICIT_WIND=='OLD' or 'NEW' ?
407 !
408 zsource(:,:) = 0. ! heat Eq source term initialization: c dz dT/dt = d/dz(k dT/dz) + Source
409 !
410 IF(io%CISBA == 'DIF')THEN
411 !
412 !* 2.a Compute sub-surface soil coupling coefficients: upward sweep
413 ! ------------------------------------------------------------
414 ! Upward sweep of the tridiagnal matrix using R&M method. Also compute
415 ! interfacial thermal conductivity to layer thickness ratio (W m-2 K-1)
416 ! These coefficients are used to compute the temperature profile implicitly.
417 !
418  CALL tridiag_ground_rm_coefs(ptstep, pd_g, ztgo, psoilhcapz, psoilcondz, &
419  zsource(:,1:jngrnd), ptdeep_a, kk%XTDEEP, &
420  ztconda_delz_g, zsoil_coef_a, zsoil_coef_b)
421 !
422 ! Here we repeat this for the snowpack: but note, this is just
423 ! to better estimate surface fluxes via the surface-sub surface heat
424 ! Flux term (we do not actually solve
425 ! the snow T profile here since fractional coverage not included).
426 ! We start from base of soil up through snow
427 ! to surface. This gives coefficients which are fully implicit
428 ! from the base of the soil to the snow surface, so numerically it is
429 ! quite robust. Note, this only corresponds to the snow-covered part of grid box,
430 ! so it is more accurate as the snow fraction approaches unity.
431 ! Starting from snowpack surface downward to base of ground:
432 !
433  jl = 1
434  zd(:,jl) = dmk%XSNOWDZ(:,1)
435  zt(:,jl) = ztno(:,1)
436  zhcapz(:,jl) = psnowhcapz(:,1)
437  zcondz(:,jl) = psnowcondz(:,1)
438  zsource(:,jl) = 0. ! Included in energy budget
439  DO jk=2,jnsnow
440  jl = jl + 1
441  DO jj=1,jnpts
442  zd(jj,jl) = zd(jj,jl-1) + dmk%XSNOWDZ(jj,jk)
443  zt(jj,jl) = ztno(jj,jk)
444  zhcapz(jj,jl) = psnowhcapz(jj,jk)
445  zcondz(jj,jl) = psnowcondz(jj,jk)
446  zsource(jj,jl) = dek%XSWNET_NS(jj)*(ptau_n(jj,jk-1)-ptau_n(jj,jk))
447  ENDDO
448  ENDDO
449  jl = jl + 1
450  zd(:,jl) = pd_g(:,1)
451  zt(:,jl) = ztgo(:,1)
452  zhcapz(:,jl) = pcheatg(:)/pd_g(:,1)
453  zcondz(:,jl) = psoilcondz(:,1)
454  zsource(:,jl) = dek%XSWNET_NS(:)*ptau_n(:,jnsnow)
455  DO jk=2,jngrnd
456  jl = jl + 1
457  DO jj=1,jnpts
458  zd(jj,jl) = pd_g(jj,jk)
459  zt(jj,jl) = ztgo(jj,jk)
460  zhcapz(jj,jl) = psoilhcapz(jj,jk)
461  zcondz(jj,jl) = psoilcondz(jj,jk)
462  zsource(jj,jl) = 0.
463  ENDDO
464  ENDDO
465 !
466 ! Get coefficients from upward sweep (starting from soil base to snow surface):
467 !
468  CALL tridiag_ground_rm_coefs(ptstep, zd, zt, zhcapz, zcondz, zsource, &
469  ptdeep_a, kk%XTDEEP, ztconda_delz_n, zcoef_a, zcoef_b)
470 !
471  zsnow_coef_a(:,2) = zcoef_a(:,2)
472  zsnow_coef_b(:,2) = zcoef_b(:,2)
473 !
474  zgcond1(:) = psoilcondz(:,1) ! save uppermost soil thermal condcutivity
475 !
476 ELSE
477 !
478  zsoil_coef_a(:,2) = (ptstep/xday)/(1.0 + ptstep/xday)
479  zsoil_coef_b(:,2) = ztgo(:,2) /(1.0 + ptstep/xday)
480 
481  ztconda_delz_g(:) = (2*xpi/xday)/pct(:)
482 
483 ! - Soil thermal conductivity
484 ! is implicit in Force-Restore soil method, so it
485 ! must be backed-out of surface thermal coefficients
486 ! (Etchevers and Martin 1997):
487 
488  zgcond1(:) = (4*xpi/xday)/( dmk%XCG(:)*dmk%XCG(:)/(pd_g(:,1)*pct(:)) )
489 
490 
491  jl = 1
492  zd(:,jl) = dmk%XSNOWDZ(:,1)
493  zt(:,jl) = ztno(:,1)
494  zhcapz(:,jl) = psnowhcapz(:,1)
495  zcondz(:,jl) = psnowcondz(:,1)
496  zsource(:,jl) = 0. ! Included in energy budget
497  DO jk=2,jnsnow
498  jl = jl + 1
499  DO jj=1,jnpts
500  zd(jj,jl) = zd(jj,jl-1) + dmk%XSNOWDZ(jj,jk)
501  zt(jj,jl) = ztno(jj,jk)
502  zhcapz(jj,jl) = psnowhcapz(jj,jk)
503  zcondz(jj,jl) = psnowcondz(jj,jk)
504  zsource(jj,jl) = dek%XSWNET_NS(jj)*(ptau_n(jj,jk-1)-ptau_n(jj,jk))
505  ENDDO
506  ENDDO
507  jl = jl + 1
508  zd(:,jl) = pd_g(:,1)
509  zt(:,jl) = ztgo(:,1)
510  zhcapz(:,jl) = 1/pct(:)
511  zcondz(:,jl) = zgcond1(:)
512  zsource(:,jl) = dek%XSWNET_NS(:)*ptau_n(:,jnsnow)
513 
514 ! Get coefficients from upward sweep (starting from soil base to snow surface):
515 !
516  CALL tridiag_ground_rm_coefs(ptstep, zd(:,1:jl), zt(:,1:jl), zhcapz(:,1:jl), zcondz(:,1:jl), &
517  zsource(:,1:jl), ptdeep_a, kk%XTDEEP, ztconda_delz_n, &
518  zcoef_a(:,1:jl), zcoef_b(:,1:jl))
519 
520  zsnow_coef_a(:,2) = zcoef_a(:,2)
521  zsnow_coef_b(:,2) = zcoef_b(:,2)
522 !
523 ENDIF
524 !
525 ! Interfacial ground-snowbase thermal conductivity divided by interfacial dz:
526 !
527 ztconda_delz_ng(:) = 2/((dmk%XSNOWDZ(:,jnsnow)/psnowcondz(:,jnsnow))+(pd_g(:,1)/zgcond1(:) ))
528 !
529 !
530 !* 3. Pseudo humidity factors (-) and effective latent heat (J kg-1)
531 ! ---------------------------------------------------------
532 !
533 ! Compute the average flux heat exchange coefficient for the canopy: (kg m-2 s-1)
534 ! Numerical: let get very small (fluxes can become essentially negligible), but not zero
535 !
536 pflxc_v_c(:) = pflxc_vg_c(:)*(1.-pek%XPSN(:)) + pflxc_vn_c(:)*pek%XPSN(:)*(1.-zpsna(:))
537 pflxc_v_c(:) = max(pflxc_v_c(:), zertol_flx_c)
538 
539 ! Understory vegetation and ground factors:
540 
541 zfff(:) = kk%XFF(:)*( (1.0 - kk%XFFROZEN(:))*(xlvtt/pltt(:)) + &
542  kk%XFFROZEN(:) *(xlstt/pltt(:)) )
543 
544 zhn(:) = (1.0-pek%XPSN(:)-kk%XFF(:))*( &
545  pleg_delta(:) *(1.0-pfrozen1(:))*(xlvtt/pltt(:)) &
546  + plegi_delta(:)* pfrozen1(:) *(xlstt/pltt(:)) ) + zfff(:)
547 
548 zhs(:) = (1.0-pek%XPSN(:)-kk%XFF(:))*( &
549  dk%XHUG(:) *pleg_delta(:) *(1.0-pfrozen1(:)) *(xlvtt/pltt(:)) &
550  + phugi(:)*plegi_delta(:)* pfrozen1(:) *(xlstt/pltt(:)) ) + zfff(:)
551 
552 ! adjust for local use in solution (since they are multiplied by 1-psn herein):
553 
554 zhn(:) = zhn(:)/max(1.0 - pek%XPSN(:) , zertol)
555 
556 zhs(:) = zhs(:)/max(1.0 - pek%XPSN(:) , zertol)
557 
558 ! Vegetation canopy factors:
559 
560 phvgs(:) = (1.-zpsna(:))*pek%XPSN(:) *phvn(:)*(pflxc_vn_c(:)/pflxc_v_c(:)) + &
561  (1.-pek%XPSN(:))*phvg(:)*(pflxc_vg_c(:)/pflxc_v_c(:))
562 
563 phvns(:) = (1.-zpsna(:))*pek%XPSN(:) * (pflxc_vn_c(:)/pflxc_v_c(:)) + &
564  (1.-pek%XPSN(:))* (pflxc_vg_c(:)/pflxc_v_c(:))
565 
566 ! - total canopy H factor (including intercepted snow)
567 
568 zhvs(:) = (1.-ppsncv(:))*(xlvtt/pltt(:))*phvgs(:) + &
569  ppsncv(:) *(xlstt/pltt(:))*phvns(:)
570 
571 ! Snow latent heating factor:
572 ! NOTE, for now we consider only snow sublimation
573 ! (not evaporation from snow liquid)
574 !
575 zhns = (xlstt/pltt(:))
576 !
577 !
578 !* 4. Transform atmospheric coupling coefficients for T and q
579 ! ---------------------------------------------------------
580 !
581 ! Transform coupling coefficients from flux form to scalar form for local
582 ! use in the energy budgets.
583 !
584 ! - first, to shorten computations a bit, define a snow fraction product
585 
586 zpsnag(:) = 1.0 - pek%XPSN(:)*ppsna(:)
587 
588 ! T coefficients: where : TA = PET_B_COEF_P + PET_A_COEF_P*TC + PET_C_COEF_P*TN
589 
590 zwork(:) = pthrma_ta(:)*( 1.0 + ppet_a_coef(:)*( &
591  pflxc_c_a(:)*zpsnag(:) + pflxc_n_a(:)*pek%XPSN(:)*ppsna(:)) )
592 zpet_a_coef_p(:) = ppet_a_coef(:)*pflxc_c_a(:)*zpsnag(:)*pthrma_tc(:)/zwork(:)
593 zpet_b_coef_p(:) = ( ppet_b_coef(:) - pthrmb_ta(:) + &
594  ppet_a_coef(:)*(pflxc_c_a(:)*zpsnag(:)*(pthrmb_tc(:)-pthrmb_ta(:)) + &
595  pflxc_n_a(:)*pek%XPSN(:)*ppsna(:)*(pthrmb_tn(:)-pthrmb_ta(:)) ) ) /zwork(:)
596 zpet_c_coef_p(:) = ppet_a_coef(:)*pflxc_n_a(:)*pek%XPSN(:)*ppsna(:)*pthrma_tn(:) /zwork(:)
597 
598 ! q coefficients:
599 
600 zwork(:) = 1.0 + ppeq_a_coef(:)*(pflxc_c_a(:)*zpsnag(:) + &
601  pflxc_n_a(:)*pek%XPSN(:)*ppsna(:)*zhns)
602 zpeq_a_coef_p(:) = ppeq_a_coef(:)*pflxc_c_a(:)*zpsnag(:) /zwork(:)
603 zpeq_b_coef_p(:) = ppeq_b_coef(:) /zwork(:)
604 zpeq_c_coef_p(:) = ppeq_a_coef(:)*pflxc_n_a(:)*pek%XPSN(:)*ppsna(:)*zhns/zwork(:)
605 
606 
607 !* 5. Compute canopy air coefficients (T and q)
608 ! ---------------------------------------------------------
609 
610 
611 ! - Canopy air T coefs, where : TC = COEFA_TC + COEFB_TC*TV + COEFC_TC*TG + COEFD_TC*TN
612 
613 zwork(:) = pflxc_c_a(:) *(pthrma_tc(:)-pthrma_ta(:)*zpet_a_coef_p(:))*zpsnag(:) &
614  + pflxc_v_c(:) *pthrma_tc(:) &
615  + pflxc_g_c(:) *pthrma_tc(:)*(1.0-pek%XPSN(:)) &
616  + pflxc_n_c(:) *pthrma_tc(:)* pek%XPSN(:) *(1.0-ppsna(:))
617 
618 zcoefa_tc(:) = (pflxc_c_a(:) * zpsnag(:) *(pthrma_ta(:)*zpet_b_coef_p(:)-pthrmb_tc(:)+pthrmb_ta(:)) &
619  + pflxc_v_c(:) * (pthrmb_tv(:)-pthrmb_tc(:)) &
620  + pflxc_g_c(:) * (pthrmb_tg(:)-pthrmb_tc(:))*(1.0-pek%XPSN(:)) &
621  + pflxc_n_c(:) * (pthrmb_tn(:)-pthrmb_tc(:))* pek%XPSN(:) *(1.0-ppsna(:)) &
622  )/zwork(:)
623 
624 zcoefb_tc(:) = pflxc_v_c(:)*pthrma_tv(:)/zwork(:)
625 
626 zcoefc_tc(:) = pflxc_g_c(:)*pthrma_tg(:)*(1.0-pek%XPSN(:))/zwork(:)
627 
628 zcoefd_tc(:) =(pflxc_n_c(:)*pthrma_tn(:)*pek%XPSN(:)*(1.0-ppsna(:)) + &
629  pflxc_c_a(:) *pthrma_ta(:)*zpet_c_coef_p(:)*zpsnag(:) ) /zwork(:)
630 
631 !- Canopy air q coefs, where : QC = COEFA_QC + COEFB_QC*TV + COEFC_QC*TG + COEFD_QC*TN
632 
633 zwork(:) = pflxc_c_a(:) *(1.-zpeq_a_coef_p(:))*zpsnag(:) &
634  + pflxc_v_c(:)* zhvs(:) &
635  + pflxc_g_c(:) *zhn(:) *(1.0-pek%XPSN(:)) &
636  + pflxc_n_c(:) *zhns(:)* pek%XPSN(:) *(1.0-ppsna(:))
637 zwork(:) = max(zertol, zwork(:))
638 
639 zcoefa_qc(:) = ( pflxc_c_a(:) *zpeq_b_coef_p(:)*zpsnag(:) &
640  + pflxc_v_c(:) *zhvs(:)*(pqsat_v(:)-pdqsat_v(:)*ztvo(:) ) &
641  + pflxc_g_c(:) *zhs(:) *(pqsat_g(:)-pdqsat_g(:)*ztgo(:,1))*(1.0-pek%XPSN(:)) &
642  + pflxc_n_c(:) *zhns(:)*(pqsati_n(:)-pdqsati_n(:)*ztno(:,1))* &
643  pek%XPSN(:)*(1.0-ppsna(:)) &
644  )/zwork(:)
645 
646 zcoefb_qc(:) = pflxc_v_c(:) *zhvs(:)*pdqsat_v(:) /zwork(:)
647 
648 zcoefc_qc(:) = pflxc_g_c(:) *zhs(:) *pdqsat_g(:)*(1.0-pek%XPSN(:))/zwork(:)
649 
650 zcoefd_qc(:) = pflxc_n_c(:) *zhns(:)*pdqsati_n(:)* pek%XPSN(:)*(1.0-ppsna(:))/zwork(:)
651 
652 !* 6. Surface Energy Budget(s) coefficients
653 ! -------------------------------------
654 ! Each of the 'N' energy budgets is linearized, so we have
655 ! 'N' linear equations and 'N' unknowns. Here we set up the coefficients.
656 ! For computations here, make snow radiative terms relative to snow surface:
657 
658 zwork(:) = 1/max(zertol, pek%XPSN(:))
659 
660 zrnet_nn(:) = (dek%XSWNET_NS(:) + dek%XLWNET_N(:))*zwork(:)
661 zrnet_n_dtnn(:) = plwnet_n_dtn(:) *zwork(:)
662 zrnet_n_dtgn(:) = plwnet_n_dtg(:) *zwork(:)
663 zrnet_n_dtvn(:) = plwnet_n_dtv(:) *zwork(:)
664 
665 ! Tv coefs, where TV = BETA_V + ALPHA_V*TG + GAMMA_V*TN
666 
667 !
668 zwork(:) = (pcheatv(:)/ptstep) - plwnet_v_dtv(:) &
669  + pflxc_v_c(:) * ( pthrma_tv(:) - pthrma_tc(:)*zcoefb_tc(:) &
670  + pltt(:)*zhvs(:)*(pdqsat_v(:) - zcoefb_qc(:)) )
671 
672 zbeta_v(:) = ( (pcheatv(:)/ptstep)*ztvo(:) + dek%XLWNET_V(:) + dek%XSWNET_V(:) &
673  - plwnet_v_dtv(:)*ztvo(:) - plwnet_v_dtg(:)*ztgo(:,1) - plwnet_v_dtn(:)*ztno(:,1) &
674  - pflxc_v_c(:)*( pthrmb_tv(:)-pthrmb_tc(:)-pthrma_tc(:)*zcoefa_tc(:) &
675  + pltt(:)*zhvs(:)*(pqsat_v(:) - pdqsat_v(:)*ztvo(:) &
676  - zcoefa_qc(:)) ) )/zwork(:)
677 
678 zalpha_v(:) = (plwnet_v_dtg(:) + pflxc_v_c(:)*(pthrma_tc(:)*zcoefc_tc(:) &
679  + pltt(:)*zhvs(:)*zcoefc_qc(:) ) )/zwork(:)
680 
681 zgamma_v(:) = (plwnet_v_dtn(:) + pflxc_v_c(:)*(pthrma_tc(:)*zcoefd_tc(:) &
682  + pltt(:)*zhvs(:)*zcoefd_qc(:) ) )/zwork(:)
683 
684 ! Tg coefs, where TG = BETA_G + ALPHA_G*TV + GAMMA_G*TN
685 
686 zwork(:) = (pcheatg(:)/ptstep) - plwnet_g_dtg(:) &
687  + (1.0-pek%XPSN(:))*pflxc_g_c(:)*( (pthrma_tg(:) - pthrma_tc(:)*zcoefc_tc(:)) &
688  + pltt(:)*(zhs(:)*pdqsat_g(:) - zhn(:)*zcoefc_qc(:)) ) &
689  + ztconda_delz_g(:)*(1.0-zsoil_coef_a(:,2)) &
690  + pek%XPSN(:)*ztconda_delz_ng(:)
691 
692 zbeta_g(:) = ( (pcheatg(:)/ptstep)*ztgo(:,1) + dek%XLWNET_G(:) + dek%XSWNET_G(:) &
693  - plwnet_g_dtv(:)*ztvo(:) - plwnet_g_dtg(:)*ztgo(:,1) - plwnet_g_dtn(:)*ztno(:,1) &
694  - (1.0-pek%XPSN(:))*pflxc_g_c(:)*( pthrmb_tg(:)-pthrmb_tc(:)-pthrma_tc(:)*zcoefa_tc(:) &
695  + pltt(:)*(zhs(:)*(pqsat_g(:) - pdqsat_g(:)*ztgo(:,1)) &
696  - zhn(:)*zcoefa_qc(:)) ) &
697  + ztconda_delz_g(:)*zsoil_coef_b(:,2) &
698  + pek%XPSN(:)*ztconda_delz_ng(:)*ztno(:,jnsnow) )/zwork(:)
699 
700 zalpha_g(:) = (plwnet_g_dtv(:) + pflxc_g_c(:)*(1.0-pek%XPSN(:))*( pthrma_tc(:)*zcoefb_tc(:) &
701  + pltt(:)*zhn(:)*zcoefb_qc(:) ) )/zwork(:)
702 
703 zgamma_g(:) = (plwnet_g_dtn(:) + pflxc_g_c(:)*(1.0-pek%XPSN(:))*( pthrma_tc(:)*zcoefd_tc(:) &
704  + pltt(:)*zhn(:)*zcoefd_qc(:) ) )/zwork(:)
705 
706 ! Tn coefs, where TN = BETA_N + ALPHA_N*TV + GAMMA_N*TG
707 
708 zwork(:) = (pcheatn(:)/ptstep) - zrnet_n_dtnn(:) &
709  + pflxc_n_c(:)*(1.-ppsna(:))*( pthrma_tn(:) - pthrma_tc(:)*zcoefd_tc(:) &
710  + (pltt(:)*zhns)*(pdqsati_n(:) - zcoefd_qc(:)) ) &
711  + pflxc_n_a(:)* ppsna(:)*( &
712  pthrma_tn(:) - pthrma_ta(:)*(zpet_a_coef_p(:)*zcoefd_tc(:) + zpet_c_coef_p(:)) &
713  + (pltt(:)*zhns)*(pdqsati_n(:)*(1.0-zpeq_c_coef_p(:)) - zpeq_a_coef_p(:)*zcoefd_qc(:)) ) &
714  + ztconda_delz_n(:)*(1.0-zsnow_coef_a(:,2))
715 
716 zbeta_n(:) = ( (pcheatn(:)/ptstep)*ztno(:,1) + zrnet_nn(:) + dmk%XHPSNOW(:) + dek%XMELTADV(:) &
717  - zrnet_n_dtvn(:)*ztvo(:) - zrnet_n_dtgn(:)*ztgo(:,1) - zrnet_n_dtnn(:)*ztno(:,1) &
718  - pflxc_n_c(:)*(1.-ppsna(:))*( pthrmb_tn(:) - pthrmb_tc(:) - pthrma_tc(:)*zcoefa_tc(:) &
719  + (pltt(:)*zhns)*(pqsati_n(:) - pdqsati_n(:)*ztno(:,1) &
720  - zcoefa_qc(:)) ) &
721  - pflxc_n_a(:)*ppsna(:)*( pthrmb_tc(:) - pthrmb_ta(:) - &
722  pthrma_ta(:)*(zpet_b_coef_p(:) + zcoefa_tc(:)*zpet_a_coef_p(:)) &
723  + (pltt(:)*zhns)*((pqsati_n(:) - pdqsati_n(:)*ztno(:,1))*(1.0-zpeq_c_coef_p(:)) &
724  - zpeq_b_coef_p(:) - zpeq_a_coef_p(:)*zcoefa_qc(:)) ) &
725  + ztconda_delz_n(:)*zsnow_coef_b(:,2) )/zwork(:)
726 
727 zalpha_n(:) = ( zrnet_n_dtvn(:) + pflxc_n_c(:)*(1.-ppsna(:))*( pthrma_tc(:)*zcoefb_tc(:) &
728  + (pltt(:)*zhns)*zcoefb_qc(:) ) &
729  + pflxc_n_a(:)* ppsna(:) *( pthrma_ta(:)*zcoefb_tc(:)*zpet_a_coef_p(:) &
730  + (pltt(:)*zhns)*zcoefb_qc(:)*zpeq_a_coef_p(:) ) )/zwork(:)
731 
732 zgamma_n(:) = ( zrnet_n_dtgn(:) + pflxc_n_c(:)*(1.-ppsna(:))*( pthrma_tc(:)*zcoefc_tc(:) &
733  + (pltt(:)*zhns)*zcoefc_qc(:)) &
734  + pflxc_n_a(:)* ppsna(:) *( pthrma_ta(:)*zcoefc_tc(:)*zpet_a_coef_p(:) &
735  + (pltt(:)*zhns)*zcoefc_qc(:)*zpeq_a_coef_p(:) ) )/zwork(:)
736 
737 !* 7. Solve multiple energy budgets simultaneously (using an implicit time scheme)
738 ! ----------------------------------------------------------------------------
739 ! Also compute certain needed diagnostics, like the canopy air T and q, and T and q at
740 ! the lowest model level: They are used within the current patch to compute implicit or explicit
741 ! fluxes (depending upon the values of the atmospheric Implicit Coupling (IC) coefficients)
742 
743 
744 WHERE(pek%XPSN(:) > 0.0)
745 
746  zwork(:) = 1.0 - zalpha_v(:)*zalpha_g(:)
747  zbeta_p_v(:) = (zbeta_v(:) + zalpha_v(:)*zbeta_g(:) )/zwork(:)
748  zalpha_p_v(:) = (zgamma_v(:) + zalpha_v(:)*zgamma_g(:))/zwork(:)
749 
750  zwork(:) = 1.0 - zgamma_g(:)*zgamma_n(:)
751  zbeta_p_n(:) = (zbeta_n(:) + zgamma_n(:)*zbeta_g(:) )/zwork(:)
752  zalpha_p_n(:) = (zalpha_n(:) + zgamma_n(:)*zalpha_g(:))/zwork(:)
753 
754  dmk%XSNOWTEMP(:,1) = (zbeta_p_n(:) + zalpha_p_n(:)*zbeta_p_v(:))/ &
755  (1.0 - zalpha_p_n(:)*zalpha_p_v(:) )
756 
757 ! Since the fluxes are passed to the snow scheme, we can simply limit Tn here
758 ! for flux computations (to make sure fluxes correspond to a snow sfc which
759 ! doesn't exceed it's physical limit, Tf). The new real snow Tn consistent with these fluxes
760 ! (and the T-profile within the snow) will be computed within the snow scheme.
761 
762  psnowliq(:,1) = psnowliq(:,1) + &
763  max(0., (dmk%XSNOWTEMP(:,1)-xtt)*psnowhcapz(:,1)*dmk%XSNOWDZ(:,1)/(xlmtt*xrholw)) ! m
764 
765  dmk%XSNOWTEMP(:,1) = min(xtt, dmk%XSNOWTEMP(:,1))
766 
767  pek%XTV(:) = zbeta_p_v(:) + zalpha_p_v(:)*dmk%XSNOWTEMP(:,1)
768 
769  ptg(:,1) = zbeta_g(:) + zalpha_g(:)*pek%XTV(:) + zgamma_g(:)*dmk%XSNOWTEMP(:,1)
770 
771  pek%XTC(:) = zcoefa_tc(:) + zcoefb_tc(:)*pek%XTV(:) + zcoefc_tc(:)*ptg(:,1) + zcoefd_tc(:)*dmk%XSNOWTEMP(:,1)
772 
773  pek%XQC(:) = zcoefa_qc(:) + zcoefb_qc(:)*pek%XTV(:) + zcoefc_qc(:)*ptg(:,1) + zcoefd_qc(:)*dmk%XSNOWTEMP(:,1)
774 
775 ! Lowest atmospheric level air temperature (for this patch):
776 
777  pta_ic(:) = zpet_b_coef_p(:) + zpet_a_coef_p(:) *pek%XTC(:) + zpet_c_coef_p(:) *dmk%XSNOWTEMP(:,1)
778 
779 ! Lowest atmospheric level specific humidity (for this patch):
780 ! - First, compute the surface specific humidity of the snow:
781 
782  zwork(:) = zhns(:)*( pqsati_n(:) + pdqsati_n(:)*(dmk%XSNOWTEMP(:,1) - ztno(:,1)) ) ! q_n+
783 
784  pqa_ic(:) = zpeq_b_coef_p(:) + zpeq_a_coef_p(:) *pek%XQC(:) + zpeq_c_coef_p(:) *zwork(:)
785 
786 ! diagnostic snow thermal flux: surface to sub-surface thermal transfer
787 
788 ! ZRESTOREN(:) = PEK%XPSN(:)*ZTCONDA_DELZ_N(:)*(DMK%XSNOWTEMP(:)*(1.0-ZSNOW_COEF_A(:,2)) - ZSNOW_COEF_B(:,2))
789 
790 ELSEWHERE ! snow free canopy-understory case:
791 
792  ptg(:,1) = (zbeta_g(:) + zalpha_g(:)*zbeta_v(:))/ &
793  (1.0 - zalpha_g(:)*zalpha_v(:) )
794 
795  pek%XTV(:) = zbeta_v(:) + zalpha_v(:)*ptg(:,1)
796 
797  pek%XTC(:) = zcoefa_tc(:) + zcoefb_tc(:)*pek%XTV(:) + zcoefc_tc(:)*ptg(:,1)
798 
799  pek%XQC(:) = zcoefa_qc(:) + zcoefb_qc(:)*pek%XTV(:) + zcoefc_qc(:)*ptg(:,1)
800 
801 ! Lowest atmospheric level air temperature (for this patch):
802 
803  pta_ic(:) = zpet_b_coef_p(:) + zpet_a_coef_p(:) *pek%XTC(:)
804 
805 ! Lowest atmospheric level specific humidity (for this patch):
806 
807  pqa_ic(:) = zpeq_b_coef_p(:) + zpeq_a_coef_p(:) *pek%XQC(:)
808 
809 ! arbitrary: (as no snow mass present)
810 
811  dmk%XSNOWTEMP(:,1) = xtt
812 
813 ! ZRESTOREN(:) = 0.0
814 
815 END WHERE
816 !
817 !* 8. Solve for sub-surface test snow temperature profile
818 ! -----------------------------------------------------------------------------
819 ! Compute test sub-surface snow temperatures: this improves time split estimate of
820 ! surface to sub-surface flux estimates. Note that the sub-surface
821 ! snow temperatures are "test" temperatures, with final "true" values
822 ! computed within the snow routine.
823 ! But we also include simple hydrology and refreezing since this can have
824 ! a significant impact during melt events on the sub-surface test
825 ! snow Temperature profile...
826 !
827 !
828  CALL tridiag_ground_rm_soln(zt,zcoef_a,zcoef_b)
829 !
830 ! Update Test T and Liquid content of snow:
831 !
832 DO jk=2,jnsnow
833  DO jj=1,jnpts
834  IF(pek%XPSN(jj) > 0.0)THEN
835  psnowliq(jj,jk) = psnowliq(jj,jk) + max(0., (zt(jj,jk)-xtt)* &
836  psnowhcapz(jj,jk)*dmk%XSNOWDZ(jj,jk)/(xlmtt*xrholw)) ! m
837  dmk%XSNOWTEMP(jj,jk) = min(xtt,zt(jj,jk))
838  ENDIF
839  ENDDO
840 ENDDO
841 !
842 ! Tipping bucket snow hydrology: update Liq
843 ! NOTE this mimicks what is assumed to be done in the snow scheme. If a more sophisticated
844 ! snow hydrology scheme is used, this code should be adapted.
845 !
846 zwholdmax(:,:) = snow3lhold(psnowrho,dmk%XSNOWDZ) ! m
847 zwork(:) = max(0., psnowliq(:,1)-zwholdmax(:,1))
848 psnowliq(:,1) = psnowliq(:,1) - zwork(:)
849 DO jk=2,jnsnow
850  DO jj=1,jnpts
851  psnowliq(jj,jk) = psnowliq(jj,jk) + zwork(jj)
852  zwork(jj) = max(0., psnowliq(jj,jk)-zwholdmax(jj,jk))
853  psnowliq(jj,jk) = psnowliq(jj,jk) - zwork(jj)
854  ENDDO
855 ENDDO
856 psnowliq(:,:) = max(0.0, psnowliq(:,:)) ! numerical check
857 !
858 ! Now, possibly refreeze liquid water which has flowed into a layer,
859 ! thus reducing liquid water and warming the snowpack:
860 !
861 DO jk=2,jnsnow
862  DO jj=1,jnpts
863  IF(pek%XPSN(jj) > 0.0)THEN
864  dmk%XSNOWTEMP(jj,jk) = dmk%XSNOWTEMP(jj,jk) + psnowliq(jj,jk)*(xlmtt*xrholw)/ &
865  (psnowhcapz(jj,jk)*max(1.e-6,dmk%XSNOWDZ(jj,jk))) ! K
866  zwork(jj) = max(0., (xtt-dmk%XSNOWTEMP(jj,jk))* &
867  psnowhcapz(jj,jk)*dmk%XSNOWDZ(jj,jk)/(xlmtt*xrholw)) ! m
868  psnowliq(jj,jk) = psnowliq(jj,jk) - zwork(jj)
869  dmk%XSNOWTEMP(jj,jk) = min(xtt,dmk%XSNOWTEMP(jj,jk))
870  ENDIF
871  ENDDO
872 ENDDO
873 !
874 !* 9. Solve soil temperature profile (implicitly coupled to surface energy budgets)
875 ! -----------------------------------------------------------------------------
876 ! The back-substitution of sub-surface soil T profile
877 ! (update all temperatures *below* the surface)
878 !
879 IF(io%CISBA == 'DIF')THEN
880  CALL tridiag_ground_rm_soln(ptg,zsoil_coef_a,zsoil_coef_b)
881 ELSE
882  ptg(:,2) = zsoil_coef_b(:,2) + zsoil_coef_a(:,2)*ptg(:,1)
883 ENDIF
884 !
885 ! Diagnose (semi-implicit) flux across ground base:
886 ! (semi-implicit if T imposed, explicit if flux imposed)
887 !
888 WHERE(kk%XTDEEP(:) == xundef)
889  pdeep_flux(:) = 0.0
890 ELSEWHERE
891  zwork(:) = psoilcondz(:,jngrnd)*2/(pd_g(:,jngrnd)-pd_g(:,jngrnd-1)) ! (W/m2/K)
892  pdeep_flux(:) = zwork(:)*(kk%XTDEEP(:) - ptg(:,jngrnd))/ &
893  (1. - zwork(:)*ptdeep_a(:)) ! (W/m2)
894 END WHERE
895 !
896 !* 10. Temperature tendencies
897 ! ----------------------
898 !
899 ! Compute energy budget tendencies (for flux computations)
900 ! and sub-sfc soil tendencies (K) (for phase changes)
901 
902 pdeltat_g(:) = ptg(:,1) - ztgo(:,1)
903 pdeltat_v(:) = pek%XTV(:) - ztvo(:)
904 pdeltat_n(:) = dmk%XSNOWTEMP(:,1) - ztno(:,1)
905 !
906 !
907 !* 11. Flux Diagnostics
908 ! ----------------
909 !
910 ! Locally implicit (with respect to the ground T) snow-ground heat flux (W m-2).
911 ! This is a first estimate, since the final fully implicit flux
912 ! is computed in the snow routine: any differences
913 ! between this flux estimate and the final one are
914 ! transferred to the soil as heating/cooling, thus
915 ! conserving energy.
916 !
917 pgrndflux(:) = pek%XPSN(:)*ztconda_delz_ng(:)*( dmk%XSNOWTEMP(:,jnsnow) - ptg(:,1) )
918 !
919 !
920 !* 12. Energy Storage Diagnostics (W m-2)
921 ! ----------------------------------
922 !
923 pdelheatg_sfc(:) = pcheatg(:)*pdeltat_g(:)/ptstep
924 pdelheatv_sfc(:) = pcheatv(:)*pdeltat_v(:)/ptstep
925 !
926 IF(io%CISBA == 'DIF')THEN
927 
928 ! Flux between surface and sub-surface (W m-2):
929 
930  dek%XRESTORE(:) = (ptg(:,1) - ptg(:,2))* 2/( ((pd_g(:,2)-pd_g(:,1))/psoilcondz(:,2)) + &
931  ( pd_g(:,1) /psoilcondz(:,1)) )
932 !
933 !
934 !* 12.a Energy Storage Diagnostics (W m-2): DIF
935 ! ---------------------------------------
936 !
937 ! These terms are used for computing energy budget diagnostics.
938 !
939 !
940  pdelheatg(:) = pdelheatg_sfc(:) ! initialize
941  DO jk=2,jngrnd
942  DO jj=1,jnpts
943  pdelheatg(jj) = pdelheatg(jj) + psoilhcapz(jj,jk)*(pd_g(jj,jk)-pd_g(jj,jk-1))* &
944  (ptg(jj,jk) - ztgo(jj,jk))/ptstep
945  ENDDO
946  ENDDO
947 !
948 ELSE
949 
950 !* 12.b Energy Storage Diagnostics (W m-2): Force Restore
951 ! -------------------------------------------------
952 !
953 ! Flux between surface and sub-surface (W m-2):
954 
955  dek%XRESTORE(:) = (2*xpi/xday)*(ptg(:,1) - ptg(:,2))/pct(:)
956 
957 ! These terms are used for computing energy budget diagnostics.
958 !
959  pdelheatg(:) = pdelheatg_sfc(:) + dek%XRESTORE(:)
960 !
961 ENDIF
962 
963 !
964 !* 13. Additional Diagnostics
965 ! ----------------------
966 !
967 ! Here compute the updated (time t+dt) effective reference level specific heat capacity:
968 ! (just a diagnostic here):
969 !
970 IF (io%CCPSURF=='DRY') THEN
971  pk%XCPS(:) = xcpd
972 ELSEIF(.NOT.lcpl_arp)THEN
973  pk%XCPS(:) = xcpd + ( xcpv - xcpd ) * pek%XQC(:)
974 ENDIF
975 !
976 ! These latent heats are used to convert between
977 ! latent heat and water mass fluxes:
978 !
979 pk%XLVTT(:) = pltt(:)
980 pk%XLSTT(:) = pltt(:)
981 !
982 !
983 IF (lhook) CALL dr_hook('E_BUDGET_MEB',1,zhook_handle)
984 !
985 END SUBROUTINE e_budget_meb
986 
987 
subroutine tridiag_ground_rm_soln(PSOLN, PA_COEF, PB_COEF)
real, parameter xsnowdzmin
real, save xcpd
Definition: modd_csts.F90:63
real, save xlvtt
Definition: modd_csts.F90:70
real, save xpi
Definition: modd_csts.F90:43
real, save xlstt
Definition: modd_csts.F90:71
real, parameter xundef
subroutine e_budget_meb(IO, KK, PK, PEK, DK, DEK, DMK, PTSTEP, PLTT, PPS, PCT, PTDEEP_A, PD_G, PS
Definition: e_budget_meb.F90:8
integer, parameter jprb
Definition: parkind1.F90:32
real, save xcpv
Definition: modd_csts.F90:63
real, save xday
Definition: modd_csts.F90:45
real, save xcl
Definition: modd_csts.F90:65
logical lhook
Definition: yomhook.F90:15
real, save xrholw
Definition: modd_csts.F90:64
real, save xtt
Definition: modd_csts.F90:66
subroutine tridiag_ground_rm_coefs(PTSTEP, PDEPTH, PTEMP, PHEATCAP, PCONDTRM, PSOURCE, PTDEEP_A, PTDEEP_B, PCONDA_DELZ, PA_COEF, PB_COEF)
real, save xlmtt
Definition: modd_csts.F90:72