1 | subroutine conductionT(nz,z,dt,T,Tsurf,Tsurfp1,ti,rhoc,Fgeotherm,Fsurf) |
---|
2 | !*********************************************************************** |
---|
3 | ! conductionT: program to calculate the diffusion of temperature |
---|
4 | ! into the ground with prescribed surface temperature |
---|
5 | ! and variable thermal properties on irregular grid |
---|
6 | ! Crank-Nicholson scheme, flux conservative |
---|
7 | ! |
---|
8 | ! Eqn: rhoc*T_t = (k*T_z)_z |
---|
9 | ! BC (z=0): T=T(t) |
---|
10 | ! BC (z=L): heat flux = Fgeotherm |
---|
11 | ! |
---|
12 | ! nz = number of grid points |
---|
13 | ! dt = time step |
---|
14 | ! T = vertical temperature profile [K] (in- and output) |
---|
15 | ! Tsurf, Tsurfp1 = surface temperatures at times n and n+1 |
---|
16 | ! ti = thermal inertia [J m^-2 K^-1 s^-1/2] VECTOR |
---|
17 | ! rhoc = rho*c heat capacity per volume [J m^-3 K^-1] VECTOR |
---|
18 | ! ti and rhoc are not allowed to vary in the layers immediately |
---|
19 | ! adjacent to the surface or the bottom |
---|
20 | ! Fgeotherm = geothermal heat flux at bottom boundary [W/m^2] |
---|
21 | ! Fsurf = heat flux at surface [W/m^2] (output) |
---|
22 | ! |
---|
23 | ! Grid: surface is at z=0 |
---|
24 | ! T(1) is at z(1); ...; T(i) is at z(i) |
---|
25 | ! k(i) is midway between z(i-1) and z(i) |
---|
26 | ! rhoc(i) is midway between z(i-1) and z(i) |
---|
27 | !*********************************************************************** |
---|
28 | implicit none |
---|
29 | |
---|
30 | integer, intent(IN) :: nz |
---|
31 | real*8, intent(IN) :: z(nz), dt, Tsurf, Tsurfp1, ti(nz), rhoc(nz) |
---|
32 | real*8, intent(IN) :: Fgeotherm |
---|
33 | real*8, intent(INOUT) :: T(nz) |
---|
34 | real*8, intent(OUT) :: Fsurf |
---|
35 | integer i |
---|
36 | real*8 alpha(nz), k(nz), gamma(nz), buf |
---|
37 | real*8 a(nz), b(nz), c(nz), r(nz) |
---|
38 | |
---|
39 | ! set some constants |
---|
40 | k(:) = ti(:)**2/rhoc(:) ! thermal conductivity |
---|
41 | alpha(1) = k(2)*dt/rhoc(1)/(z(2)-z(1))/z(2) |
---|
42 | gamma(1) = k(1)*dt/rhoc(1)/z(1)/z(2) |
---|
43 | do i=2,nz-1 |
---|
44 | buf = dt/(z(i+1)-z(i-1)) |
---|
45 | alpha(i) = k(i+1)*buf*2./(rhoc(i)+rhoc(i+1))/(z(i+1)-z(i)) |
---|
46 | gamma(i) = k(i)*buf*2./(rhoc(i)+rhoc(i+1))/(z(i)-z(i-1)) |
---|
47 | enddo |
---|
48 | buf = dt/(z(nz)-z(nz-1))**2 |
---|
49 | gamma(nz) = k(nz)*buf/(rhoc(nz)+rhoc(nz)) ! assumes rhoc(nz+1)=rhoc(nz) |
---|
50 | |
---|
51 | ! elements of tridiagonal matrix |
---|
52 | a(:) = -gamma(:) ! a(1) is not used |
---|
53 | b(:) = 1. + alpha(:) + gamma(:) |
---|
54 | c(:) = -alpha(:) ! c(nz) is not used |
---|
55 | b(nz) = 1. + gamma(nz) |
---|
56 | |
---|
57 | ! Set RHS |
---|
58 | r(1)= alpha(1)*T(2) + (1.-alpha(1)-gamma(1))*T(1) + gamma(1)*(Tsurf+Tsurfp1) |
---|
59 | do concurrent (i=2:nz-1) |
---|
60 | r(i) = gamma(i)*T(i-1) + (1.-alpha(i)-gamma(i))*T(i) + alpha(i)*T(i+1) |
---|
61 | enddo |
---|
62 | r(nz) = gamma(nz)*T(nz-1) + (1.-gamma(nz))*T(nz) + & |
---|
63 | & dt/rhoc(nz)*Fgeotherm/(z(nz)-z(nz-1)) ! assumes rhoc(nz+1)=rhoc(nz) |
---|
64 | |
---|
65 | ! Solve for T at n+1 |
---|
66 | call tridag(a,b,c,r,T,nz) ! update by tridiagonal inversion |
---|
67 | |
---|
68 | Fsurf = -k(1)*(T(1)-Tsurfp1)/z(1) ! heat flux into surface |
---|
69 | |
---|
70 | end subroutine conductionT |
---|