SURFEX  V8_0
Surfex V8_0 release
 All Classes Files Functions Variables
tridiag_ground_rm_coefs.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 tridiag_ground_rm_coefs(PTSTEP,PDEPTH,PTEMP,PHEATCAP,PCONDTRM, &
7  psource,ptdeep_a,ptdeep_b,pconda_delz,pa_coef,pb_coef)
8 !
9 !
10 !!**** *TRIDIAG_GROUND_RM_COEF*
11 !!
12 !! PURPOSE
13 !! -------
14 !
15 ! This routine computes the coefficients of a Tridiagnoal matrix using
16 ! the method of Richtmeyer and Morton (1967): this routine corresponds to the **upward sweep**
17 ! The lower boundary condition is based on the linear eq ==> TN = B + A FN
18 ! Where B and A are imposed and correspond to either a Dirichlet (prescribed lower boundary T)
19 ! or a lower boundary flux (Neumann type). If B is FLAGGED, then
20 ! lower boundary flux is imposed as zero.
21 ! This routine is used to
22 ! eliminate T2(t+dt) (sub-surface T at time t+dt) from an energy balance Eq (where T1=Tsfc)
23 ! NOTE the solution is computed from TRIDIAG_GROUND_RM_SOLN.F90
24 !
25 !
26 !!** METHOD
27 !! ------
28 !
29 !! EXTERNAL
30 !! --------
31 !!
32 !! none
33 !!
34 !! IMPLICIT ARGUMENTS
35 !! ------------------
36 !!
37 !!
38 !! REFERENCE
39 !! ---------
40 !
41 ! Richtmeyer, R. and K. Morton, 1967: Difference method for initial values problems,
42 ! Interscience Publishers, 2.
43 !
44 !! AUTHOR
45 !! ------
46 !!
47 !! A. Boone * Meteo-France *
48 !!
49 !! MODIFICATIONS
50 !! -------------
51 !! Original 21/03/11
52 !! Modif 23/02/12 A. Boone: Optimization
53 !! Modif 03/2013 A. Boone: MEB
54 !! Modif 06/2013 A. Boone: use TN=B+A FN form for lower BC
55 !
56 !-------------------------------------------------------------------------------
57 !
58 !* 0. DECLARATIONS
59 ! ------------
60 !
61 USE modd_surf_par, ONLY : xundef
62 !
63 USE yomhook ,ONLY : lhook, dr_hook
64 USE parkind1 ,ONLY : jprb
65 !
66 IMPLICIT NONE
67 !
68 !* 0.1 Declarations of arguments
69 !
70 REAL, INTENT(IN) :: ptstep ! time-step (s)
71 REAL, DIMENSION(:,:), INTENT(IN) :: pdepth ! soil layer depth (m)
72 REAL, DIMENSION(:,:), INTENT(IN) :: ptemp ! surface and sub-surface soil
73 ! ! temperature profile (K)
74 REAL, DIMENSION(:,:), INTENT(IN) :: pheatcap ! soil heat capacity (J/K/m3)
75 REAL, DIMENSION(:,:), INTENT(IN) :: pcondtrm ! soil thermal conductivity (W/m/K)
76 REAL, DIMENSION(:,:), INTENT(IN) :: psource ! soil heat source function (J/m2/s)
77 REAL, DIMENSION(:), INTENT(IN) :: ptdeep_a, ptdeep_b
78 ! ! PTDEEP_A = Deep soil temperature
79 ! ! coefficient depending on flux (m2/K/W)
80 ! ! PTDEEP_B = Deep soil temperature (K)
81 ! ! (prescribed)
82 ! ! which models heating/cooling from
83 ! ! below the diurnal wave penetration
84 ! ! (surface temperature) depth. If it
85 ! ! is FLAGGED as undefined, then the zero
86 ! ! flux lower BC is applied.
87 ! ! Tdeep = PTDEEP_B + PTDEEP_A * PDEEP_FLUX
88 ! ! (with PDEEP_FLUX in W/m2)
89 !
90 REAL, DIMENSION(:), INTENT(OUT) :: pconda_delz ! ratio: ground flux thermal
91  ! conductivity/
92  ! ground flux thickness (W/m2/K)
93 REAL, DIMENSION(:,:), INTENT(OUT) :: pa_coef ! RM67 A-soil coefficient (-)
94 REAL, DIMENSION(:,:), INTENT(OUT) :: pb_coef ! RM67 B-soil coefficient (K)
95 !
96 !
97 !* 0.2 Declarations of local variables
98 !
99 INTEGER :: jj, ji, inl, ini
100 REAL, DIMENSION(SIZE(PDEPTH,1),SIZE(PDEPTH,2)) :: zd_g ! soil layer thicknesses (m)
101 REAL, DIMENSION(SIZE(PDEPTH,1),SIZE(PDEPTH,2)) :: zdlz ! thickness between layer mid_points (m)
102 REAL, DIMENSION(SIZE(PDEPTH,1),SIZE(PDEPTH,2)) :: zlambda ! ratio of thermal cond to dz (W/m2/K)
103 REAL, DIMENSION(SIZE(PDEPTH,1),SIZE(PDEPTH,2)) :: zgheatcap ! effective heat capacity
104 ! ! coefficient (J/K/m2)
105 REAL, DIMENSION(SIZE(PDEPTH,1),SIZE(PDEPTH,2)) :: zthrm ! interfacial therm. cond. (W/m/K)
106 REAL, DIMENSION(SIZE(PDEPTH,1)) :: zc_coef ! working denominator for coefs
107 REAL, DIMENSION(SIZE(PDEPTH,1)) :: za_coefd !
108 REAL, DIMENSION(SIZE(PDEPTH,1)) :: zb_coefd !
109 REAL, DIMENSION(SIZE(PDEPTH,1),SIZE(PDEPTH,2)) :: zsink ! sink term (can be input)
110 !
111 REAL(KIND=JPRB) :: zhook_handle
112 !
113 !* 0.3 Declarations of local parameters
114 !
115 REAL, PARAMETER :: zdz_min = 1.e-6 ! m
116 !
117 !---------------------------------------------------------------------------
118 !
119 IF (lhook) CALL dr_hook('TRIDIAG_GROUND_RM_COEFS',0,zhook_handle)
120 !
121 !* 0. Initialization
122 ! --------------
123 !
124 ini = SIZE(pdepth,1)
125 inl = SIZE(pdepth,2)
126 !
127 !* 1. Compute needed parameters
128 ! -------------------------
129 ! Needed parameters: interfacial thermal conductivity,
130 ! layer thicknesses, and layer average heat capacities:
131 
132 ! Soil layer thicknesses, dz, from depths (base of each layer):
133 
134 zd_g(:,1) = pdepth(:,1)
135 DO jj=2,inl
136  DO ji=1,ini
137  zd_g(ji,jj) = pdepth(ji,jj) - pdepth(ji,jj-1)
138  ENDDO
139 ENDDO
140 zd_g(:,:) = max(zdz_min, zd_g(:,:)) ! just for numerical reasons
141 
142 ! distance between layer mid_points (m):
143 
144 DO jj=1,inl-1
145  DO ji=1,ini
146  zdlz(ji,jj) = (zd_g(ji,jj)+zd_g(ji,jj+1))*0.5
147  ENDDO
148 ENDDO
149 zdlz(:,inl) = zd_g(:,inl)*0.5
150 
151 ! effective heat capacity coefficient (J/K/m2):
152 
153 zgheatcap(:,:) = zd_g(:,:)*pheatcap(:,:)
154 
155 ! interfacial thermal conductivity (W/m/K):
156 
157 DO jj=1,inl-1
158  DO ji=1,ini
159  zthrm(ji,jj) = (zd_g(ji,jj)+zd_g(ji,jj+1))/ &
160  ((zd_g(ji,jj+1)/pcondtrm(ji,jj+1))+ &
161  (zd_g(ji,jj) /pcondtrm(ji,jj) ))
162  ENDDO
163 ENDDO
164 zthrm(:,inl) = pcondtrm(:,inl)
165 !
166 !
167 ! Energy sink:
168 ! NOTE for now, set this part to zero as accounted for elsewhere.
169 !!!ZSINK(:,:) = -PPHASE(:,:)*PTSTEP/ZGHEATCAP(:,:)
170 !
171 zsink(:,:) = -psource(:,:) ! J/m2/s
172 !
173 ! Thermal cond/dz ratio (W m-2 K-1):
174 !
175 zlambda(:,:) = zthrm(:,:)/zdlz(:,:)
176 !
177 ! Save sfc interfacial thermal cond/dz ratio (W m-2 K-1):
178 !
179 pconda_delz(:) = zlambda(:,1)
180 !
181 !
182 !* 2. COEFFICIENTS
183 ! ------------
184 !
185 ! Start at base of soil or snow etc...assuming an imposed lower boundary flux,
186 ! and move up towards surface:
187 
188 ! initialize:
189 
190 pa_coef(:,:) = 0.0
191 pb_coef(:,:) = 0.0
192 
193 ! lowest layer: flux is prescribed (can be 0)
194 ! where GBFLUX = tcond/dz ( T_N - T_N+1 ) (W m-2)
195 
196 WHERE(ptdeep_b(:) == xundef) ! no flux at model base
197 
198  zc_coef(:) = (zgheatcap(:,inl)/ptstep) &
199  + zlambda(:,inl-1)
200  pa_coef(:,inl) = zlambda(:,inl-1)/zc_coef(:)
201  pb_coef(:,inl) = ( ptemp(:,inl)*(zgheatcap(:,inl)/ptstep) &
202  - zsink(:,inl) )/zc_coef(:)
203 
204  za_coefd(:) = xundef
205  zb_coefd(:) = xundef
206 
207 ELSEWHERE
208 
209 ! corresponds to Dirichlet or Neumann type lower BC (non-zero flux)
210 
211  zc_coef(:) = 1. - ptdeep_a(:)*zlambda(:,inl)
212  za_coefd(:) = -zlambda(:,inl)/zc_coef(:)
213  zb_coefd(:) = zlambda(:,inl)*ptdeep_b(:)/zc_coef(:)
214 
215  zc_coef(:) = (zgheatcap(:,inl)/ptstep) &
216  + zlambda(:,inl-1) - za_coefd(:)
217  pa_coef(:,inl) = zlambda(:,inl-1)/zc_coef(:)
218  pb_coef(:,inl) = ( ptemp(:,inl)*(zgheatcap(:,inl)/ptstep) &
219  + zb_coefd(:) - zsink(:,inl) )/zc_coef(:)
220 
221 END WHERE
222 
223 ! interior layers:
224 
225 DO jj=inl-1,2,-1
226  DO ji=1,ini
227  zc_coef(ji) = (zgheatcap(ji,jj)/ptstep) &
228  + zlambda(ji,jj)*(1.0-pa_coef(ji,jj+1)) &
229  + zlambda(ji,jj-1)
230  pa_coef(ji,jj) = zlambda(ji,jj-1)/zc_coef(ji)
231  pb_coef(ji,jj) = ( ptemp(ji,jj)*(zgheatcap(ji,jj)/ptstep) &
232  + zlambda(ji,jj)*pb_coef(ji,jj+1) &
233  - zsink(ji,jj) )/zc_coef(ji)
234  ENDDO
235 ENDDO
236 !
237 ! NOTE: uppermost coefficients have been kept at
238 ! zero (initial value)/not computed as they're
239 ! not used in computations (implicit in surface E budget
240 ! computed elsewhere)
241 !
242 IF (lhook) CALL dr_hook('TRIDIAG_GROUND_RM_COEFS',1,zhook_handle)
243 !-------------------------------------------------------------------
244 END SUBROUTINE tridiag_ground_rm_coefs
subroutine tridiag_ground_rm_coefs(PTSTEP, PDEPTH, PTEMP, PHEATCAP, PCONDTRM, PSOURCE, PTDEEP_A, PTDEEP_B, PCONDA_DELZ, PA_COEF, PB_COEF)