source: trunk/LMDZ.VENUS/libf/phyvenus/soil.F @ 3954

Last change on this file since 3954 was 3898, checked in by emillour, 8 months ago

Venus PCM:
More cleanup and prettyfying and preparing things for OpenMP.
Turned clmain_ideal into a module; added intent() to arguments.
Added THREADPRIVATE clause for saved variables, and English comments,
in radlwsw_NewtonCool and soil routines.
EM

File size: 7.4 KB
Line 
1      MODULE soil_mod
2     
3      IMPLICIT NONE
4     
5      INTEGER,PARAMETER :: nsoilmx=11 ! number of sub-surface soil layers
6     
7      CONTAINS
8
9      SUBROUTINE soil(ptimestep, knon, ptsrf, ptsoil,
10     s          pcapcal, pfluxgrd)
11
12c=======================================================================
13c
14c   Auteur:  Frederic Hourdin     30/01/92
15c   -------
16c
17c   objet:  computation of : the soil temperature evolution
18c   ------                   the surfacic heat capacity "Capcal"
19c                            the surface conduction flux pcapcal
20c
21c
22c   Method: implicit time integration
23c   -------
24c   Consecutive ground temperatures are related by:
25c           T(k+1) = C(k) + D(k)*T(k)  (1)
26c   the coefficients C and D are computed at the t-dt time-step.
27c   Routine structure:
28c   1)new temperatures are computed  using (1)
29c   2)C and D coefficients are computed from the new temperature
30c     profile for the t+dt time-step
31c   3)the coefficients A and B are computed where the diffusive
32c     fluxes at the t+dt time-step is given by
33c            Fdiff = A + B Ts(t+dt)
34c     or     Fdiff = F0 + Capcal (Ts(t+dt)-Ts(t))/dt
35c            with F0 = A + B (Ts(t))
36c                 Capcal = B*dt
37c           
38c   Interface:
39c   ----------
40c
41c   Arguments:
42c   ----------
43c   ptimestep            physical timestep (s)
44c   ptsrf(klon)          surface temperature at time-step t (K)
45c   ptsoil(klon,nsoilmx) temperature inside the ground (K)
46c   pcapcal(klon)        surfacic specific heat (W*m-2*s*K-1)
47c   pfluxgrd(klon)       surface diffusive flux from ground (Wm-2)
48c   
49c=======================================================================
50c   declarations:
51c   -------------
52
53      use dimphy, only: klon
54      use clesphys_mod, only: inertie
55
56      IMPLICIT NONE
57
58c-----------------------------------------------------------------------
59c  arguments
60c  ---------
61
62      REAL, intent(IN) :: ptimestep ! physics time step (s)
63      INTEGER, intent(IN) :: knon ! number of columns
64      REAL, intent(IN) :: ptsrf(klon) ! surface temperature (K)
65      REAL, intent(OUT) :: ptsoil(klon,nsoilmx) ! sub-surface temperature (K)
66      REAL, intent(OUT) :: pcapcal(klon) ! surfacic specific heat (W*m-2*s*K-1)
67      real,intent(out) :: pfluxgrd(klon) ! surface diffusive flux from ground (Wm-2)
68
69c-----------------------------------------------------------------------
70c  local arrays
71c  ------------
72
73      INTEGER ig,jk
74      REAL zdz2(nsoilmx),z1(klon)
75      REAL min_period,dalph_soil
76      REAL ztherm_i(klon)
77
78c   local saved variables:
79c   ----------------------
80      REAL,SAVE :: dz1(nsoilmx),dz2(nsoilmx)
81c$OMP THREADPRIVATE(dz1,dz2)
82      REAL,allocatable,save :: zc(:,:),zd(:,:)
83c$OMP THREADPRIVATE(zc,zd)
84      REAL,SAVE :: lambda
85c$OMP THREADPRIVATE(lambda)
86      LOGICAL,SAVE :: firstcall=.true.
87c$OMP THREADPRIVATE(firstcall)
88
89c-----------------------------------------------------------------------
90c   Depths:
91c   -------
92
93      REAL fz,rk,fz1,rk1,rk2
94      fz(rk)=fz1*(dalph_soil**rk-1.)/(dalph_soil-1.)
95
96      pfluxgrd(:) = 0.
97 
98      ! on Venus thermal inertia is assumed constant over the globe
99      DO ig = 1, knon
100          ztherm_i(ig)   = inertie
101      ENDDO
102
103      IF (firstcall) THEN
104
105         allocate(zc(klon,nsoilmx),zd(klon,nsoilmx))
106
107c-----------------------------------------------------------------------
108c   ground levels
109c   grnd=z/l where l is the skin depth of the diurnal cycle:
110c   --------------------------------------------------------
111
112c VENUS : A REVOIR !!!!
113         min_period=20000. ! in seconds
114         dalph_soil=2.    ! ratio between successive layer sizes
115
116         OPEN(99,file='soil.def',status='old',form='formatted',err=9999)
117         READ(99,*) min_period
118         READ(99,*) dalph_soil
119         PRINT*,'Discretization for the soil model'
120         PRINT*,'First level e-folding depth',min_period,
121     s   '   dalph',dalph_soil
122         CLOSE(99)
1239999     CONTINUE
124
125c   The first soil layer depth, based on min_period
126         fz1=sqrt(min_period/3.14)
127
128         DO jk=1,nsoilmx
129            rk1=jk
130            rk2=jk-1
131            dz2(jk)=fz(rk1)-fz(rk2)
132         ENDDO
133         DO jk=1,nsoilmx-1
134            rk1=jk+.5
135            rk2=jk-.5
136            dz1(jk)=1./(fz(rk1)-fz(rk2))
137         ENDDO
138         lambda=fz(.5)*dz1(1)
139         PRINT*,'full layers, intermediate layers (seconds)'
140         DO jk=1,nsoilmx
141            rk=jk
142            rk1=jk+.5
143            rk2=jk-.5
144            PRINT *,'fz=',
145     .               fz(rk1)*fz(rk2)*3.14,fz(rk)*fz(rk)*3.14
146         ENDDO
147         
148c-----------------------------------------------------------------------
149c   Computation of the Cgrd and Dgrd coefficient for the next step:
150c   ---------------------------------------------------------------
151         DO jk=1,nsoilmx
152            zdz2(jk)=dz2(jk)/ptimestep
153         ENDDO
154
155         DO ig=1,knon
156            z1(ig)=zdz2(nsoilmx)+dz1(nsoilmx-1)
157            zc(ig,nsoilmx-1)=
158     $          zdz2(nsoilmx)*ptsoil(ig,nsoilmx)/z1(ig)
159            zd(ig,nsoilmx-1)=dz1(nsoilmx-1)/z1(ig)
160         ENDDO
161
162         DO jk=nsoilmx-1,2,-1
163            DO ig=1,knon
164               z1(ig)=1./(zdz2(jk)+dz1(jk-1)+dz1(jk)
165     $            *(1.-zd(ig,jk)))
166               zc(ig,jk-1)=
167     s         (ptsoil(ig,jk)*zdz2(jk)+dz1(jk)*zc(ig,jk))
168     $             *z1(ig)
169               zd(ig,jk-1)=dz1(jk-1)*z1(ig)
170            ENDDO
171         ENDDO
172         firstcall =.false.
173
174      ENDIF !--not firstcall
175
176c-----------------------------------------------------------------------
177c   Computation of the soil temperatures using the Cgrd and Dgrd
178c  coefficient computed at the previous time-step:
179c  -----------------------------------------------
180
181c        temperature in the first soil layer
182         DO ig=1,knon
183            ptsoil(ig,1)=(lambda*zc(ig,1)+ptsrf(ig))/
184     s      (lambda*(1.-zd(ig,1))+1.)
185         ENDDO
186
187c        temperatures in the other soil layers
188         DO jk=1,nsoilmx-1
189            DO ig=1,knon
190               ptsoil(ig,jk+1)=zc(ig,jk)+zd(ig,jk)*ptsoil(ig,jk)
191            ENDDO
192         ENDDO
193
194c-----------------------------------------------------------------------
195c   Computation of the Cgrd and Dgrd coefficient for the next step:
196c   ---------------------------------------------------------------
197
198      DO jk=1,nsoilmx
199         zdz2(jk)=dz2(jk)/ptimestep
200      ENDDO
201
202      DO ig=1,knon
203         z1(ig)=zdz2(nsoilmx)+dz1(nsoilmx-1)
204         zc(ig,nsoilmx-1)=
205     $       zdz2(nsoilmx)*ptsoil(ig,nsoilmx)/z1(ig)
206         zd(ig,nsoilmx-1)=dz1(nsoilmx-1)/z1(ig)
207      ENDDO
208
209      DO jk=nsoilmx-1,2,-1
210         DO ig=1,knon
211            z1(ig)=1./(zdz2(jk)+dz1(jk-1)+dz1(jk)
212     $         *(1.-zd(ig,jk)))
213            zc(ig,jk-1)=
214     s      (ptsoil(ig,jk)*zdz2(jk)+dz1(jk)*zc(ig,jk))
215     $          *z1(ig)
216            zd(ig,jk-1)=dz1(jk-1)*z1(ig)
217         ENDDO
218      ENDDO
219
220c-----------------------------------------------------------------------
221c   computation of the surface diffusive flux from ground and
222c   calorific capacity of the ground:
223c   ---------------------------------
224
225      DO ig=1,knon
226         pfluxgrd(ig)=ztherm_i(ig)*dz1(1)*
227     s   (zc(ig,1)+(zd(ig,1)-1.)*ptsoil(ig,1))
228         pcapcal(ig)=ztherm_i(ig)*
229     s   (dz2(1)+ptimestep*(1.-zd(ig,1))*dz1(1))
230         z1(ig)=lambda*(1.-zd(ig,1))+1.
231         pcapcal(ig)=pcapcal(ig)/z1(ig)
232         pfluxgrd(ig) = pfluxgrd(ig)
233     s   + pcapcal(ig) * (ptsoil(ig,1) * z1(ig)
234     $       - lambda * zc(ig,1)
235     $       - ptsrf(ig))
236     s   /ptimestep
237      ENDDO
238
239     
240      END SUBROUTINE soil
241     
242      END MODULE soil_mod
Note: See TracBrowser for help on using the repository browser.