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

Last change on this file since 4231 was 4229, checked in by dubos, 6 years ago

simple_physics : beautify code

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