source: trunk/LMDZ.COMMON/libf/evolution/NS_conductionQ.F90 @ 3525

Last change on this file since 3525 was 3493, checked in by jbclement, 3 weeks ago

PEM:

  • Renaming of Norbert Schorghofer's subroutines with the prefix 'NS_';
  • Making the extension of all NS's subroutines as '.F90';
  • Deletion of the wrapper subroutine;
  • Making the initialization, variables management and arguments of the main subroutine for the dynamic computation of ice table to be more suitable.

JBC

File size: 4.2 KB
Line 
1subroutine conductionQ(nz,z,dt,Qn,Qnp1,T,ti,rhoc,emiss,Tsurf, &
2     &     Fgeotherm,Fsurf)
3!***********************************************************************
4!   conductionQ:  program to calculate the diffusion of temperature
5!                 into the ground and thermal emission at the surface
6!                 with variable thermal properties on irregular grid
7!   Crank-Nicolson scheme, flux conservative
8!                          uses Samar's radiation formula
9!   Eqn: rhoc*T_t = (k*T_z)_z
10!   BC (z=0): Q(t) + kT_z = em*sig*T^4
11!   BC (z=L): heat flux = Fgeotherm
12!
13!   nz = number of grid points
14!   dt = time step
15!   Qn,Qnp1 = net solar insolation at time steps n and n+1 [W/m^2]
16!   T = vertical temperature profile [K]  (in- and output) 
17!   ti = thermal inertia [J m^-2 K^-1 s^-1/2]  VECTOR
18!   rhoc = rho*c  VECTOR where rho=density [kg/m^3] and
19!                              c=specific heat [J K^-1 kg^-1]
20!   ti and rhoc are not allowed to vary in the layers immediately
21!               adjacent to the surface or the bottom
22!   emiss = emissivity
23!   Tsurf = surface temperature [K]  (in- and output)
24!   Fgeotherm = geothermal heat flux at bottom boundary [W/m^2]
25!   Fsurf = heat flux at surface [W/m^2]  (output)
26!
27!   Grid: surface is at z=0
28!         z(0)=0, z(2)=3*z(1), i.e., the top layer has half the width
29!         T(1) is at z(1); ...; T(i) is at z(i)
30!         k(i), rhoc(i), ti(i) are midway between z(i-1) and z(i)
31!     
32!   originally written by Samar Khatiwala, 2001
33!   extended to variable thermal properties
34!         and irregular grid by Norbert Schorghofer
35!   added predictor-corrector 9/2019 
36!***********************************************************************
37
38  implicit none
39  real*8, parameter :: sigSB=5.6704d-8
40 
41  integer, intent(IN) :: nz
42  real*8, intent(IN) :: z(nz), dt, Qn, Qnp1, ti(nz),rhoc(nz)
43  real*8, intent(IN) :: emiss, Fgeotherm
44  real*8, intent(INOUT) :: T(nz), Tsurf
45  real*8, intent(OUT) :: Fsurf
46  integer i, iter
47  real*8 k(nz), k1, alpha(nz), gamma(nz), Tr
48  real*8 a(nz), b(nz), c(nz), r(nz), Told(nz)
49  real*8 arad, brad, ann, annp1, bn, buf, dz, beta
50 
51  ! set some constants
52  k(:) = ti(:)**2/rhoc(:) ! thermal conductivity
53  dz = 2.*z(1)
54  beta = dt/rhoc(1)/(2.*dz**2)   ! assumes rhoc(0)=rhoc(1)
55  alpha(1) = beta*k(2)
56  gamma(1) = beta*k(1)
57  do i=2,nz-1
58     buf = dt/(z(i+1)-z(i-1))
59     alpha(i) = 2.*k(i+1)*buf/(rhoc(i)+rhoc(i+1))/(z(i+1)-z(i))
60     gamma(i) = 2.*k(i)*buf/(rhoc(i)+rhoc(i+1))/(z(i)-z(i-1))
61  enddo
62  buf = dt/(z(nz)-z(nz-1))**2
63  gamma(nz) = k(nz)*buf/(2*rhoc(nz)) ! assumes rhoc(nz+1)=rhoc(nz)
64 
65  k1 = k(1)/dz
66 
67  ! elements of tridiagonal matrix
68  a(:) = -gamma(:)   !  a(1) is not used
69  b(:) = 1. + alpha(:) + gamma(:) !  b(1) has to be reset at every timestep
70  c(:) = -alpha(:)   !  c(nz) is not used
71  b(nz) = 1. + gamma(nz)
72
73  Tr = Tsurf            ! 'reference' temperature
74  iter = 0
75  Told(:) = T(:)
7630 continue  ! in rare case of iterative correction
77
78  ! Emission
79  arad = -3.*emiss*sigSB*Tr**4
80  brad = 2.*emiss*sigSB*Tr**3
81  ann = (Qn-arad)/(k1+brad)
82  annp1 = (Qnp1-arad)/(k1+brad)
83  bn = (k1-brad)/(k1+brad)
84  b(1) = 1. + alpha(1) + gamma(1) - gamma(1)*bn
85 
86  ! Set RHS         
87  r(1) = gamma(1)*(annp1+ann) + &
88       &     (1.-alpha(1)-gamma(1)+gamma(1)*bn)*T(1) + alpha(1)*T(2)
89  do concurrent (i=2:nz-1)
90     r(i) = gamma(i)*T(i-1) + (1.-alpha(i)-gamma(i))*T(i)+ alpha(i)*T(i+1)
91  enddo
92  r(nz) = gamma(nz)*T(nz-1) + (1.-gamma(nz))*T(nz) &
93       &     + dt/rhoc(nz)*Fgeotherm/(z(nz)-z(nz-1)) ! assumes rhoc(nz+1)=rhoc(nz)
94
95  ! Solve for T at n+1
96  call tridag(a,b,c,r,T,nz) ! update by tridiagonal inversion
97 
98  Tsurf = 0.5*(annp1 + bn*T(1) + T(1)) ! (T0+T1)/2
99
100  ! iterative predictor-corrector
101  if ((Tsurf > 1.2*Tr .or. Tsurf < 0.8*Tr) .and. iter<10) then  ! linearization error expected
102     ! redo until Tr is within 20% of new surface temperature
103     ! (under most circumstances, the 20% threshold is never exceeded)
104     iter = iter+1
105     Tr = sqrt(Tr*Tsurf)  ! linearize around an intermediate temperature
106     T(:) = Told(:)
107     goto 30
108  endif
109  !if (iter>=5) print *,'consider taking shorter time steps',iter
110  !if (iter>=10) print *,'warning: too many iterations'
111 
112  Fsurf = - k(1)*(T(1)-Tsurf)/z(1) ! heat flux into surface
113end subroutine conductionQ
Note: See TracBrowser for help on using the repository browser.