/[lmdze]/trunk/phylmd/Interface_surf/soil.f90
ViewVC logotype

Diff of /trunk/phylmd/Interface_surf/soil.f90

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 330 by guez, Wed Jul 31 14:55:23 2019 UTC revision 344 by guez, Tue Nov 12 15:18:14 2019 UTC
# Line 2  module soil_m Line 2  module soil_m
2    
3    IMPLICIT NONE    IMPLICIT NONE
4    
5      private fz
6    
7  contains  contains
8    
9    SUBROUTINE soil(nisurf, snow, tsurf, tsoil, soilcap, soilflux)    SUBROUTINE soil(nisurf, snow, tsurf, tsoil, soilcap, soilflux)
# Line 31  contains Line 33  contains
33      ! F0 = A + B (Ts(t))      ! F0 = A + B (Ts(t))
34      ! Soilcap = B * dt      ! Soilcap = B * dt
35    
36        ! Libraries:
37        use jumble, only: new_unit
38    
39      use comconst, only: dtphys      use comconst, only: dtphys
     USE indicesol, only: nbsrf, is_lic, is_oce, is_sic, is_ter  
40      USE dimphy, only: klon      USE dimphy, only: klon
41      USE dimsoil, only: nsoilmx      USE dimsoil, only: nsoilmx
42        USE indicesol, only: nbsrf, is_lic, is_oce, is_sic, is_ter
43      USE suphec_m, only: rtt      USE suphec_m, only: rtt
44    
45      INTEGER, intent(in):: nisurf ! sub-surface index      INTEGER, intent(in):: nisurf ! surface type index
46      REAL, intent(in):: snow(:) ! (knon)      REAL, intent(in):: snow(:) ! (knon)
47      REAL, intent(in):: tsurf(:) ! (knon) surface temperature at time-step t (K)      REAL, intent(in):: tsurf(:) ! (knon) surface temperature at time-step t (K)
48    
49      real, intent(inout):: tsoil(:, :) ! (knon, nsoilmx)      real, intent(inout):: tsoil(:, :) ! (knon, nsoilmx)
50      ! temperature inside the ground (K)      ! temperature inside the ground (K), layer 1 nearest to the surface
51    
52      REAL, intent(out):: soilcap(:) ! (knon)      REAL, intent(out):: soilcap(:) ! (knon)
53      ! specific heat per unit surface (W m-2 s K-1)      ! specific heat per unit surface (W m-2 s K-1)
# Line 51  contains Line 56  contains
56      ! surface diffusive flux from ground (W m-2)      ! surface diffusive flux from ground (W m-2)
57    
58      ! Local:      ! Local:
59        INTEGER knon, ig, jk, unit
     INTEGER knon, ig, jk  
60      REAL zdz2(nsoilmx)      REAL zdz2(nsoilmx)
61      real z1(size(tsurf), nbsrf) ! (knon, nbsrf)      real z1(size(tsurf), nbsrf) ! (knon, nbsrf)
62      REAL min_period, dalph_soil      REAL min_period ! in s
63        real dalph_soil ! rapport entre les \'epaisseurs de 2 couches successives
64      REAL ztherm_i(size(tsurf)) ! (knon)      REAL ztherm_i(size(tsurf)) ! (knon)
65      REAL, save:: dz1(nsoilmx), dz2(nsoilmx)      REAL, save:: dz1(nsoilmx), dz2(nsoilmx)
66      REAL, save:: zc(klon, nsoilmx, nbsrf), zd(klon, nsoilmx, nbsrf)      REAL, save:: zc(klon, nsoilmx, nbsrf), zd(klon, nsoilmx, nbsrf)
67      REAL, save:: lambda      REAL, save:: lambda
68      LOGICAL:: firstsurf(nbsrf) = .TRUE.      LOGICAL:: firstsurf(nbsrf) = .TRUE.
69      REAL:: isol = 2000., isno = 2000., iice = 2000.      REAL, parameter:: isol = 2000., isno = 2000., iice = 2000.
70        REAL rk, fz1, rk1, rk2 ! depths
     ! Depths:  
     REAL rk, fz1, rk1, rk2  
71    
72      !-----------------------------------------------------------------------      !-----------------------------------------------------------------------
73    
74      knon = size(tsurf)      knon = size(tsurf)
75    
76      ! Calcul de l'inertie thermique. On initialise \`a iice m\^eme      ! Calcul de l'inertie thermique. On initialise \`a iice m\^eme
77      ! au-dessus d'un point de mer au cas o\`u le point de mer devienne      ! au-dessus d'un point de mer pour le cas o\`u le point de mer
78      ! point de glace au pas suivant. On corrige si on a un point de      ! deviendrait point de glace au pas suivant. On corrige si on a un
79      ! terre avec ou sans glace.      ! point de terre avec ou sans glace.
80    
81      IF (nisurf==is_sic) THEN      select case (nisurf)
82         DO ig = 1, knon      case (is_sic)
83            ztherm_i(ig) = iice         DO ig = 1, knon
84            IF (snow(ig) > 0.) ztherm_i(ig) = isno            IF (snow(ig) > 0.) then
85         END DO               ztherm_i(ig) = isno
86      ELSE IF (nisurf==is_lic) THEN            else
87         DO ig = 1, knon               ztherm_i(ig) = iice
88            ztherm_i(ig) = iice            end IF
89            IF (snow(ig) > 0.) ztherm_i(ig) = isno         END DO
90        case (is_lic)
91           DO ig = 1, knon
92              IF (snow(ig) > 0.) then
93                 ztherm_i(ig) = isno
94              else
95                 ztherm_i(ig) = iice
96              end IF
97           END DO
98        case (is_ter)
99           DO ig = 1, knon
100              IF (snow(ig) > 0.) then
101                 ztherm_i(ig) = isno
102              else
103                 ztherm_i(ig) = isol
104              end IF
105         END DO         END DO
106      ELSE IF (nisurf==is_ter) THEN      case (is_oce)
        DO ig = 1, knon  
           ztherm_i(ig) = isol  
           IF (snow(ig) > 0.) ztherm_i(ig) = isno  
        END DO  
     ELSE IF (nisurf==is_oce) THEN  
107         DO ig = 1, knon         DO ig = 1, knon
108            ztherm_i(ig) = iice            ztherm_i(ig) = iice
109         END DO         END DO
110      ELSE      case default
111         PRINT *, 'valeur d indice non prevue', nisurf         PRINT *, 'soil: unexpected subscript value:', nisurf
112         STOP 1         STOP 1
113      END IF      END select
114    
115      IF (firstsurf(nisurf)) THEN      IF (firstsurf(nisurf)) THEN
116         ! ground levels         ! ground levels
117         ! grnd=z / l where l is the skin depth of the diurnal cycle:         ! grnd=z / l where l is the skin depth of the diurnal cycle:
118    
119         min_period = 1800. ! en secondes         min_period = 1800.
120         dalph_soil = 2. ! rapport entre les epaisseurs de 2 couches succ.         dalph_soil = 2.
121           call new_unit(unit)
122         OPEN(99, FILE='soil.def', STATUS='old', FORM='formatted', ERR=9999)         OPEN(unit, FILE = 'soil.def', STATUS = 'old', action = "read", &
123         READ(99, *) min_period              position = 'rewind', ERR = 9999)
124         READ(99, *) dalph_soil         READ(unit, fmt = *) min_period
125           READ(unit, fmt = *) dalph_soil
126         PRINT *, 'Discretization for the soil model'         PRINT *, 'Discretization for the soil model'
127         PRINT *, 'First level e-folding depth', min_period, ' dalph', &         PRINT *, 'First level e-folding depth', min_period, ' dalph', &
128              dalph_soil              dalph_soil
129         CLOSE(99)         CLOSE(unit)
130  9999   CONTINUE  9999   CONTINUE
131    
132         ! la premiere couche represente un dixieme de cycle diurne         ! La premi\`ere couche repr\'esente un dixi\`eme de cycle diurne :
133         fz1 = sqrt(min_period / 3.14)         fz1 = sqrt(min_period / 3.14)
134    
135         DO jk = 1, nsoilmx         DO jk = 1, nsoilmx
136            rk1 = jk            rk1 = jk
137            rk2 = jk - 1            rk2 = jk - 1
138            dz2(jk) = fz(rk1) - fz(rk2)            dz2(jk) = fz(rk1, dalph_soil, fz1) - fz(rk2, dalph_soil, fz1)
139         END DO         END DO
140    
141         DO jk = 1, nsoilmx - 1         DO jk = 1, nsoilmx - 1
142            rk1 = jk + .5            rk1 = jk + .5
143            rk2 = jk - .5            rk2 = jk - .5
144            dz1(jk) = 1. / (fz(rk1) - fz(rk2))            dz1(jk) = 1. / (fz(rk1, dalph_soil, fz1) - fz(rk2, dalph_soil, fz1))
145         END DO         END DO
146         lambda = fz(.5) * dz1(1)  
147           lambda = fz(.5, dalph_soil, fz1) * dz1(1)
148         PRINT *, 'full layers, intermediate layers (seconds)'         PRINT *, 'full layers, intermediate layers (seconds)'
149    
150         DO jk = 1, nsoilmx         DO jk = 1, nsoilmx
151            rk = jk            rk = jk
152            rk1 = jk + .5            rk1 = jk + .5
153            rk2 = jk - .5            rk2 = jk - .5
154            PRINT *, 'fz=', fz(rk1) * fz(rk2) * 3.14, fz(rk) * fz(rk) * 3.14            PRINT *, 'fz=', fz(rk1, dalph_soil, fz1) * fz(rk2, dalph_soil, fz1) &
155                   * 3.14, fz(rk, dalph_soil, fz1) * fz(rk, dalph_soil, fz1) * 3.14
156         END DO         END DO
157         ! PB  
158         firstsurf(nisurf) = .FALSE.         firstsurf(nisurf) = .FALSE.
159      ELSE      ELSE
160         ! Computation of the soil temperatures using the Zc and Zd         ! Computation of the soil temperatures using the Zc and Zd
161         ! coefficient computed at the previous time-step:         ! coefficient computed at the previous time-step:
162    
163         ! surface temperature         ! Surface temperature:
164         DO ig = 1, knon         DO ig = 1, knon
165            tsoil(ig, 1) = (lambda * zc(ig, 1, nisurf) + tsurf(ig)) &            tsoil(ig, 1) = (lambda * zc(ig, 1, nisurf) + tsurf(ig)) &
166                 / (lambda * (1. - zd(ig, 1, nisurf)) + 1.)                 / (lambda * (1. - zd(ig, 1, nisurf)) + 1.)
167         END DO         END DO
168    
169         ! other temperatures         ! Other temperatures:
170         DO jk = 1, nsoilmx - 1         DO jk = 1, nsoilmx - 1
171            DO ig = 1, knon            DO ig = 1, knon
172               tsoil(ig, jk + 1) = zc(ig, jk, nisurf) &               tsoil(ig, jk + 1) = zc(ig, jk, nisurf) &
# Line 186  contains Line 204  contains
204         END DO         END DO
205      END DO      END DO
206    
207      ! computation of the surface diffusive flux from ground and      ! Computation of the surface diffusive flux from ground and
208      ! calorific capacity of the ground:      ! calorific capacity of the ground:
209    
210      DO ig = 1, knon      DO ig = 1, knon
211         soilflux(ig) = ztherm_i(ig) * dz1(1) * (zc(ig, 1, nisurf) + (zd(ig, 1, &         soilflux(ig) = ztherm_i(ig) * dz1(1) * (zc(ig, 1, nisurf) &
212              nisurf) - 1.) * tsoil(ig, 1))              + (zd(ig, 1, nisurf) - 1.) * tsoil(ig, 1))
213         soilcap(ig) = ztherm_i(ig) * (dz2(1) &         soilcap(ig) = ztherm_i(ig) * (dz2(1) &
214              + dtphys * (1. - zd(ig, 1, nisurf)) * dz1(1))              + dtphys * (1. - zd(ig, 1, nisurf)) * dz1(1))
215         z1(ig, nisurf) = lambda * (1. - zd(ig, 1, nisurf)) + 1.         z1(ig, nisurf) = lambda * (1. - zd(ig, 1, nisurf)) + 1.
# Line 200  contains Line 218  contains
218              * z1(ig, nisurf) - lambda * zc(ig, 1, nisurf) - tsurf(ig)) / dtphys              * z1(ig, nisurf) - lambda * zc(ig, 1, nisurf) - tsurf(ig)) / dtphys
219      END DO      END DO
220    
221    contains    END SUBROUTINE soil
222    
223      !****************************************************************
224    
225      pure real function fz(rk)    pure real function fz(rk, dalph_soil, fz1)
226    
227        real, intent(in):: rk      real, intent(in):: rk
228    
229        !-----------------------------------------      real, intent(in):: dalph_soil
230        ! rapport entre les \'epaisseurs de 2 couches successives
231    
232        fz = fz1 * (dalph_soil**rk - 1.) / (dalph_soil - 1.)      real, intent(in):: fz1 ! depth
233    
234      end function fz      !-----------------------------------------
235    
236    END SUBROUTINE soil      fz = fz1 * (dalph_soil**rk - 1.) / (dalph_soil - 1.)
237    
238      end function fz
239    
240  end module soil_m  end module soil_m

Legend:
Removed from v.330  
changed lines
  Added in v.344

  ViewVC Help
Powered by ViewVC 1.1.21