source: dynamico_lmdz/simple_physics/phyparam/physics/surface.F90 @ 4241

Last change on this file since 4241 was 4233, checked in by dubos, 6 years ago

simple_physics : enforce F2003 strictly

File size: 6.1 KB
Line 
1MODULE surface
2
3#include "use_logging.h"
4
5  IMPLICIT NONE
6  PRIVATE
7  SAVE
8
9  REAL, PARAMETER :: pi=2.*ASIN(1.)
10
11  ! common variables
12  REAL, PUBLIC ::  I_mer,I_ter,Cd_mer,Cd_ter, &
13       &           alb_mer,alb_ter,emi_mer,emi_ter
14
15  ! precomputed variables
16  REAL :: lambda
17  REAL,ALLOCATABLE :: dz1(:),dz2(:)
18  !$OMP THREADPRIVATE(dz1,dz2,zc,lambda)
19
20  ! internal state variables needed for checkpoint/restart
21  REAL, ALLOCATABLE :: zc(:,:),zd(:,:)
22  !$OMP THREADPRIVATE(zc,zd)
23
24  PUBLIC :: soil, zc, zd
25
26CONTAINS
27
28  SUBROUTINE init_soil(ngrid,nsoil)
29    INTEGER, INTENT(IN) :: ngrid, nsoil
30    REAL :: min_period,dalph_soil, rk,fz1,rk1,rk2
31    INTEGER :: jk
32
33    !-----------------------------------------------------------------------
34    !   ground levels
35    !   grnd=z/l where l is the skin depth of the diurnal cycle:
36    !   --------------------------------------------------------
37
38    WRITELOG(*,*) 'nsoil,ngrid,firstcall=',nsoil,ngrid, .TRUE.
39
40    ALLOCATE(dz1(nsoil),dz2(nsoil))
41
42    min_period=20000.
43    dalph_soil=2.
44
45    !   la premiere couche represente un dixieme de cycle diurne
46    fz1=sqrt(min_period/pi)
47
48    DO jk=1,nsoil
49       rk1=jk
50       rk2=jk-1
51       dz2(jk)=fz(rk1)-fz(rk2)
52    ENDDO
53    DO jk=1,nsoil-1
54       rk1=jk+.5
55       rk2=jk-.5
56       dz1(jk)=1./(fz(rk1)-fz(rk2))
57    ENDDO
58    lambda=fz(.5)*dz1(1)
59
60    WRITELOG(*,*) 'full layers, intermediate layers (secoonds)'
61    DO jk=1,nsoil
62       rk=jk
63       rk1=jk+.5
64       rk2=jk-.5
65       WRITELOG(*,*) fz(rk1)*fz(rk2)*pi,        &
66            &        fz(rk)*fz(rk)*pi
67    ENDDO
68    LOG_INFO('init_soil')
69
70  CONTAINS
71
72    FUNCTION fz(rk) RESULT(val)
73      REAL :: val, rk
74      val = fz1*(dalph_soil**rk-1.)/(dalph_soil-1.)
75    END FUNCTION fz
76
77  END SUBROUTINE init_soil
78
79  SUBROUTINE soil(ngrid,nsoil,firstcall,ptherm_i,          &
80       &          ptimestep,ptsrf,ptsoil,                  &
81       &          pcapcal,pfluxgrd)
82
83    !=======================================================================
84    !
85    !   Auteur:  Frederic Hourdin     30/01/92
86    !   -------
87    !
88    !   objet:  computation of : the soil temperature evolution
89    !   ------                   the surfacic heat capacity "Capcal"
90    !                            the surface conduction flux pcapcal
91    !
92    !
93    !   Method: implicit time integration
94    !   -------
95    !   Consecutive ground temperatures are related by:
96    !           T(k+1) = C(k) + D(k)*T(k)  (1)
97    !   the coefficients C and D are computed at the t-dt time-step.
98    !   Routine structure:
99    !   1)new temperatures are computed  using (1)
100    !   2)C and D coefficients are computed from the new temperature
101    !     profile for the t+dt time-step
102    !   3)the coefficients A and B are computed where the diffusive
103    !     fluxes at the t+dt time-step is given by
104    !            Fdiff = A + B Ts(t+dt)
105    !     or     Fdiff = F0 + Capcal (Ts(t+dt)-Ts(t))/dt
106    !            with F0 = A + B (Ts(t))
107    !                 Capcal = B*dt
108    !
109    !   Interface:
110    !   ----------
111    !
112    !   Arguments:
113    !   ----------
114    !   ngrid               number of grid-points
115    !   ptimestep              physical timestep (s)
116    !   pto(ngrid,nsoil)     temperature at time-step t (K)
117    !   ptn(ngrid,nsoil)     temperature at time step t+dt (K)
118    !   pcapcal(ngrid)      specific heat (W*m-2*s*K-1)
119    !   pfluxgrd(ngrid)      surface diffusive flux from ground (Wm-2)
120    !
121    !=======================================================================
122    !   declarations:
123    !   -------------
124
125
126    !-----------------------------------------------------------------------
127    !  arguments
128    !  ---------
129
130    INTEGER ngrid,nsoil
131    REAL ptimestep
132    REAL ptsrf(ngrid),ptsoil(ngrid,nsoil),ptherm_i(ngrid)
133    REAL pcapcal(ngrid),pfluxgrd(ngrid)
134    LOGICAL firstcall
135
136
137    !-----------------------------------------------------------------------
138    !  local arrays
139    !  ------------
140
141    INTEGER ig,jk
142    REAL zdz2(nsoil),z1(ngrid)
143
144    IF (firstcall) THEN
145       CALL init_soil(ngrid, nsoil)
146    ELSE
147       !-----------------------------------------------------------------------
148       !   Computation of the soil temperatures using the Cgrd and Dgrd
149       !  coefficient computed at the previous time-step:
150       !  -----------------------------------------------
151
152       !    surface temperature
153       DO ig=1,ngrid
154          ptsoil(ig,1)=(lambda*zc(ig,1)+ptsrf(ig))/                   &
155               &      (lambda*(1.-zd(ig,1))+1.)
156       ENDDO
157
158       !   other temperatures
159       DO jk=1,nsoil-1
160          DO ig=1,ngrid
161             ptsoil(ig,jk+1)=zc(ig,jk)+zd(ig,jk)*ptsoil(ig,jk)
162          ENDDO
163       ENDDO
164
165    ENDIF
166
167    !-----------------------------------------------------------------------
168    !   Computation of the Cgrd and Dgrd coefficient for the next step:
169    !   ---------------------------------------------------------------
170
171    DO jk=1,nsoil
172       zdz2(jk)=dz2(jk)/ptimestep
173    ENDDO
174
175    DO ig=1,ngrid
176       z1(ig)=zdz2(nsoil)+dz1(nsoil-1)
177       zc(ig,nsoil-1)=zdz2(nsoil)*ptsoil(ig,nsoil)/z1(ig)
178       zd(ig,nsoil-1)=dz1(nsoil-1)/z1(ig)
179    ENDDO
180
181    DO jk=nsoil-1,2,-1
182       DO ig=1,ngrid
183          z1(ig)=1./(zdz2(jk)+dz1(jk-1)+dz1(jk)*(1.-zd(ig,jk)))
184          zc(ig,jk-1)=                                                &
185               &      (ptsoil(ig,jk)*zdz2(jk)+dz1(jk)*zc(ig,jk))*z1(ig)
186          zd(ig,jk-1)=dz1(jk-1)*z1(ig)
187       ENDDO
188    ENDDO
189
190    !-----------------------------------------------------------------------
191    !   computation of the surface diffusive flux from ground and
192    !   calorific capacity of the ground:
193    !   ---------------------------------
194
195    DO ig=1,ngrid
196       pfluxgrd(ig)=ptherm_i(ig)*dz1(1)*                              &
197            &   (zc(ig,1)+(zd(ig,1)-1.)*ptsoil(ig,1))
198       z1(ig)=lambda*(1.-zd(ig,1))+1.
199       pcapcal(ig)=ptherm_i(ig)*                                      &
200            &   ptimestep*(zdz2(1)+(1.-zd(ig,1))*dz1(1))/z1(ig)
201       pfluxgrd(ig)=pfluxgrd(ig)                                      &
202            &   +pcapcal(ig)*(ptsoil(ig,1)*z1(ig)-lambda*zc(ig,1)-ptsrf(ig))   &
203            &   /ptimestep
204    ENDDO
205
206  END SUBROUTINE soil
207
208END MODULE surface
Note: See TracBrowser for help on using the repository browser.