source: trunk/LMDZ.COMMON/libf/evolution/soil.F90 @ 4175

Last change on this file since 4175 was 4170, checked in by jbclement, 13 days ago

PEM:

  • Deletion of 'flux_ssice' ('zqdsdif_tot') from the "startfi.nc" as it is not needed.
  • Using the yearly average flux for the sublimating subsurface ice instead of the value at last timestep.
  • Keeping a clear separation between the subsurface ice flux and the surface ice tendency.
  • Making sure that subsurface ice depth is well given to the PCM at the end of the PEM (ice table VS layering).

JBC

File size: 12.8 KB
RevLine 
[3989]1MODULE soil
[3991]2!-----------------------------------------------------------------------
3! NAME
4!     soil
5!
6! DESCRIPTION
7!     Soil state and properties for PEM.
8!
9! AUTHORS & DATE
10!     L. Lange, 04/2023
11!     JB Clement, 2023-2025
12!
13! NOTES
14!
15!-----------------------------------------------------------------------
[2794]16
[4065]17! DEPENDENCIES
18! ------------
19use numerics, only: dp, di, k4
20
[3991]21! DECLARATION
22! -----------
[2794]23implicit none
[2895]24
[4065]25! PARAMETERS
26! ----------
[4136]27real(dp), parameter :: rho_regolith      = 2000._dp ! Density of the martian regolith [kg/m^3], Zent et al. 1995; Buhler and Piqueux 2021
[4135]28real(dp), parameter :: regolith_porosity = 0.4_dp   ! Porosity of the martian regolith for a random loose packing of monodisperse sphere, Scott 1960
29real(dp), parameter :: breccia_porosity  = 0.1_dp   ! Porosity of breccia
30
[4110]31logical(k4),                             protected          :: do_soil            ! To run with subsurface physics
32logical(k4),                             protected          :: reg_thprop_dependp ! Regolith thermal properties depend on surface pressure
33real(dp),                                protected          :: flux_geo           ! Geothermal flux [W/m^2]
34real(dp),                                protected          :: depth_breccia      ! Depth of breccia [m]
35real(dp),                                protected          :: depth_bedrock      ! Depth of bedrock [m]
36real(dp), allocatable, dimension(:,:,:), protected, private :: TI_PCM             ! Soil thermal inertia in the "startfi.nc" at the beginning [SI]
[3991]37
[4065]38! VARIABLES
39! ---------
40real(dp), allocatable, dimension(:)     :: layer              ! Soil layer depths [m]
41real(dp), allocatable, dimension(:)     :: mlayer             ! Soil mid-layer depths [m]
42real(dp), allocatable, dimension(:,:,:) :: TI                 ! Soil thermal inertia [SI]
43real(dp), allocatable, dimension(:,:)   :: inertiedat         ! Soil thermal inertia saved as reference for current climate [SI]
44real(dp), allocatable, dimension(:,:)   :: inertiedat_PCM     ! Soil thermal inertia saved as reference for current climate in the PCM [SI]
45real(dp), allocatable, dimension(:,:)   :: mthermdiff         ! Mid-layer thermal diffusivity [SI]
46real(dp), allocatable, dimension(:,:)   :: thermdiff          ! Inter-layer thermal diffusivity [SI]
47real(dp), allocatable, dimension(:)     :: coefq              ! q_{k+1/2} coefficients [SI]
48real(dp), allocatable, dimension(:,:)   :: coefd              ! d_k coefficients [SI]
49real(dp), allocatable, dimension(:,:)   :: alph               ! alpha_k coefficients [SI]
50real(dp), allocatable, dimension(:,:)   :: beta               ! beta_k coefficients [SI]
51real(dp)                                :: mu                 ! mu coefficient [SI]
52integer(di)                             :: index_breccia      ! Last index of the depth grid before having breccia
53integer(di)                             :: index_bedrock      ! Last index of the depth grid before having bedrock
54real(dp)                                :: volcapa            ! Soil volumetric heat capacity
[3143]55
[2794]56contains
[3991]57!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
58
[3143]59!=======================================================================
[4065]60SUBROUTINE ini_soil()
[3991]61!-----------------------------------------------------------------------
62! NAME
63!     ini_soil
64!
65! DESCRIPTION
66!     Allocate soil arrays based on grid dimensions.
67!
68! AUTHORS & DATE
69!     L. Lange, 2023
70!     JB Clement, 2023-2025
71!
72! NOTES
73!
74!-----------------------------------------------------------------------
[2794]75
[4065]76! DEPENDENCIES
77! ------------
78use geometry, only: ngrid, nslope, nsoil, nsoil_PCM
79
[3991]80! DECLARATION
81! -----------
[3143]82implicit none
[2794]83
[3991]84! CODE
85! ----
[4065]86allocate(layer(nsoil))
87allocate(mlayer(0:nsoil - 1))
88allocate(TI(ngrid,nsoil,nslope))
89allocate(mthermdiff(ngrid,0:nsoil - 1))
90allocate(thermdiff(ngrid,nsoil - 1))
91allocate(coefq(0:nsoil - 1))
92allocate(coefd(ngrid,nsoil - 1))
93allocate(alph(ngrid,nsoil - 1))
94allocate(beta(ngrid,nsoil - 1))
95allocate(inertiedat(ngrid,nsoil))
[4134]96allocate(inertiedat_PCM(ngrid,nsoil_PCM))
97allocate(TI_PCM(ngrid,nsoil_PCM,nslope))
[4074]98inertiedat_PCM(:,:) = 0._dp
99TI_PCM(:,:,:) = 0._dp
[2794]100
[3989]101END SUBROUTINE ini_soil
[3991]102!=======================================================================
[2794]103
[3143]104!=======================================================================
[3989]105SUBROUTINE end_soil
[3991]106!-----------------------------------------------------------------------
107! NAME
108!     end_soil
109!
110! DESCRIPTION
111!     Deallocate all soil arrays.
112!
113! AUTHORS & DATE
114!     L. Lange, 2023
115!     JB Clement, 2023-2025
116!
117! NOTES
118!
119!-----------------------------------------------------------------------
[3143]120
[3991]121! DECLARATION
122! -----------
[3143]123implicit none
124
[3991]125! CODE
126! ----
[4065]127if (allocated(layer)) deallocate(layer)
128if (allocated(mlayer)) deallocate(mlayer)
129if (allocated(TI)) deallocate(TI)
130if (allocated(mthermdiff)) deallocate(mthermdiff)
131if (allocated(thermdiff)) deallocate(thermdiff)
132if (allocated(coefq)) deallocate(coefq)
133if (allocated(coefd)) deallocate(coefd)
134if (allocated(alph)) deallocate(alph)
135if (allocated(beta)) deallocate(beta)
136if (allocated(inertiedat)) deallocate(inertiedat)
137if (allocated(inertiedat_PCM)) deallocate(inertiedat_PCM)
138if (allocated(TI_PCM)) deallocate(TI_PCM)
[3143]139
[3989]140END SUBROUTINE end_soil
[3991]141!=======================================================================
[3143]142
[3989]143!=======================================================================
[4065]144SUBROUTINE set_soil_config(do_soil_in,reg_thprop_dependp_in,flux_geo_in,depth_breccia_in,depth_bedrock_in)
[3991]145!-----------------------------------------------------------------------
146! NAME
[4065]147!     set_soil_config
148!
149! DESCRIPTION
[4170]150!     Setter for "soil" configuration parameters.
[4065]151!
152! AUTHORS & DATE
153!     JB Clement, 02/2026
154!
155! NOTES
156!
157!-----------------------------------------------------------------------
158
159! DEPENDENCIES
160! ------------
[4110]161use utility,  only: real2str, bool2str
162use display,  only: print_msg, LVL_NFO
163use stoppage, only: stop_clean
[4065]164
165! DECLARATION
166! -----------
167implicit none
168
169! ARGUMENTS
170! ---------
171logical(k4), intent(in) :: do_soil_in, reg_thprop_dependp_in
172real(dp),    intent(in) :: flux_geo_in, depth_breccia_in, depth_bedrock_in
173
174! CODE
175! ----
176do_soil = do_soil_in
177reg_thprop_dependp = reg_thprop_dependp_in
178flux_geo = flux_geo_in
179depth_breccia = depth_breccia_in
180depth_bedrock = depth_bedrock_in
[4110]181call print_msg('do_soil            = '//bool2str(do_soil),LVL_NFO)
182call print_msg('reg_thprop_dependp = '//bool2str(reg_thprop_dependp),LVL_NFO)
183call print_msg('flux_geo           = '//real2str(flux_geo),LVL_NFO)
184call print_msg('depth_breccia      = '//real2str(depth_breccia),LVL_NFO)
185call print_msg('depth_bedrock      = '//real2str(depth_bedrock),LVL_NFO)
186if (depth_breccia < 0._dp) call stop_clean(__FILE__,__LINE__,'''depth_breccia'' must be positive!',1)
187if (depth_bedrock < 0._dp) call stop_clean(__FILE__,__LINE__,'''depth_bedrock'' must be positive!',1)
188if (depth_bedrock <= depth_breccia) call stop_clean(__FILE__,__LINE__,'''depth_bedrock'' must be greater than ''depth_breccia''!',1)
[4065]189
190END SUBROUTINE set_soil_config
191!=======================================================================
192
193!=======================================================================
194SUBROUTINE set_TI_PCM(TI_PCM_in)
195!-----------------------------------------------------------------------
196! NAME
197!     set_TI_PCM
198!
199! DESCRIPTION
200!     Setter for 'TI_PCM'.
201!
202! AUTHORS & DATE
203!     JB Clement, 01/2026
204!
205! NOTES
206!
207!-----------------------------------------------------------------------
208
209! DECLARATION
210! -----------
211implicit none
212
213! ARGUMENTS
214! ---------
215real(dp), dimension(:,:,:), intent(in) :: TI_PCM_in
216
217! CODE
218! ----
219TI_PCM(:,:,:) = TI_PCM_in(:,:,:)
220
221END SUBROUTINE set_TI_PCM
222!=======================================================================
223
224!=======================================================================
225SUBROUTINE set_inertiedat_PCM(inertiedat_PCM_in)
226!-----------------------------------------------------------------------
227! NAME
228!     set_inertiedat_PCM
229!
230! DESCRIPTION
231!     Setter for 'inertiedat_PCM'.
232!
233! AUTHORS & DATE
234!     JB Clement, 01/2026
235!
236! NOTES
237!
238!-----------------------------------------------------------------------
239
240! DECLARATION
241! -----------
242implicit none
243
244! ARGUMENTS
245! ---------
246real(dp), dimension(:,:), intent(in) :: inertiedat_PCM_in
247
248! CODE
249! ----
250inertiedat_PCM(:,:) = inertiedat_PCM_in(:,:)
251
252END SUBROUTINE set_inertiedat_PCM
253!=======================================================================
254
255!=======================================================================
[4136]256SUBROUTINE set_soil(therm_initia)
[4065]257!-----------------------------------------------------------------------
258! NAME
[3991]259!     set_soil
260!
261! DESCRIPTION
262!     Initialize soil depths and properties. Builds layer depths using
263!     exponential then power-law distribution; interpolates thermal inertia
264!     from PCM to PEM grid.
265!
266! AUTHORS & DATE
267!     E. Millour, 07/2006
268!     L. Lange, 2023
269!     JB Clement, 2023-2025
270!
271! NOTES
272!     Modifications:
273!          Aug.2010 EM: use NetCDF90 to load variables (enables using
274!                       r4 or r8 restarts independently of having compiled
275!                       the GCM in r4 or r8)
276!          June 2013 TN: Possibility to read files with a time axis
277!     The various actions and variable read/initialized are:
278!     1. Read/build layer (and midlayer) depth
279!     2. Interpolate thermal inertia and temperature on the new grid, if necessary
280!-----------------------------------------------------------------------
[3989]281
[3991]282! DEPENDENCIES
283! ------------
[4065]284use geometry, only: ngrid, nslope, nsoil, nsoil_PCM
[3989]285
[3991]286! DECLARATION
287! -----------
[3989]288implicit none
289
[3991]290! ARGUMENTS
291! ---------
[4136]292real(dp), dimension(:,:,:), intent(inout) :: therm_initia ! Thermal inertia in the PEM [SI]
[3989]293
[3991]294! LOCAL VARIABLES
295! ---------------
[4065]296integer(di) :: ig, iloop, islope ! loop counters
297real(dp)    :: alpha, lay1       ! coefficients for building layers
298real(dp)    :: index_powerlaw    ! coefficient to match the power low grid with the exponential one
[3991]299
300! CODE
301! ----
[3989]302! 1. Depth coordinate
303! -------------------
[4065]304! mlayer distribution: For the grid in common with the PCM: lay1*(1+k^(2.9)*(1-exp(-k/20))
[3989]305! Then we use a power low : lay1*alpha**(k-1/2)
306lay1 = 2.e-4
307alpha = 2
308do iloop = 0,nsoil_PCM - 1
[4065]309    mlayer(iloop) = lay1*(1 + iloop**2.9*(1._dp - exp(-real(iloop,dp)/20._dp)))
310end do
[3989]311
[4065]312do iloop = 0,nsoil - 1
313    if (lay1*(alpha**(iloop - 0.5_dp)) > mlayer(nsoil_PCM - 1)) then
[3989]314        index_powerlaw = iloop
315        exit
[4065]316    end if
317end do
[3989]318
[4065]319do iloop = nsoil_PCM,nsoil - 1
320    mlayer(iloop) = lay1*(alpha**(index_powerlaw + (iloop - nsoil_PCM) - 0.5_dp))
321end do
[3989]322
[4065]323! Build layer()
324do iloop = 1,nsoil - 1
325    layer(iloop) = (mlayer(iloop) + mlayer(iloop - 1))/2._dp
326end do
327layer(nsoil) = 2._dp*mlayer(nsoil - 1) - mlayer(nsoil - 2)
[3989]328
329
330! 2. Thermal inertia (note: it is declared in comsoil_h)
331! ------------------
332do ig = 1,ngrid
333    do islope = 1,nslope
334        do iloop = 1,nsoil_PCM
[4136]335            therm_initia(ig,iloop,islope) = TI_PCM(ig,iloop,islope)
[4065]336        end do
337        if (nsoil > nsoil_PCM) then
338            do iloop = nsoil_PCM + 1,nsoil
[4136]339                therm_initia(ig,iloop,islope) = TI_PCM(ig,nsoil_PCM,islope)
[4065]340            end do
341        end if
342    end do
343end do
[3989]344
345! 3. Index for subsurface layering
346! ------------------
347index_breccia = 1
[4065]348do iloop = 1,nsoil - 1
349    if (depth_breccia >= layer(iloop)) then
[3989]350        index_breccia = iloop
351    else
352        exit
[4065]353    end if
354end do
[3989]355
356index_bedrock = 1
[4065]357do iloop = 1,nsoil - 1
358    if (depth_bedrock >= layer(iloop)) then
[3989]359        index_bedrock = iloop
360    else
361        exit
[4065]362    end if
363end do
[3989]364
365END SUBROUTINE set_soil
[3991]366!=======================================================================
[3989]367
[4065]368!=======================================================================
369SUBROUTINE build4PCM_soil(tsoil_avg,tsoil_dev,inertiesoil4PCM,tsoil4PCM,flux_geo4PCM)
370!-----------------------------------------------------------------------
371! NAME
372!     build4PCM_soil
373!
374! DESCRIPTION
375!     Reconstructs the soil temperature profile, thermal inertia and
376!     the geothermal flux for the PCM.
377!
378! AUTHORS & DATE
379!     JB Clement, 12/2025
380!     C. Metz, 01/2026
381!
382! NOTES
383!
384!-----------------------------------------------------------------------
385
386! DEPENDENCIES
387! ------------
388use geometry, only: nsoil_PCM
[4110]389use display,  only: print_msg, LVL_NFO
[4065]390
391! DECLARATION
392! -----------
393implicit none
394
395! ARGUMENTS
396! ---------
397real(dp), dimension(:,:,:), intent(in)  :: tsoil_avg, tsoil_dev
398real(dp), dimension(:,:,:), intent(out) :: tsoil4PCM, inertiesoil4PCM
399real(dp), dimension(:,:),   intent(out) :: flux_geo4PCM
400
401! CODE
402! ----
[4110]403call print_msg('> Building soil thermal inertia for the PCM',LVL_NFO)
[4065]404inertiesoil4PCM(:,:,:) = TI(:,1:nsoil_PCM,:)
405
[4110]406call print_msg('> Building soil temperature profile for the PCM',LVL_NFO)
[4065]407tsoil4PCM(:,:,:) = tsoil_avg(:,1:nsoil_PCM,:) + tsoil_dev(:,:,:)
408
[4110]409call print_msg('> Building geothermal flux for the PCM',LVL_NFO)
[4065]410flux_geo4PCM(:,:) = (tsoil_avg(:,nsoil_PCM + 1,:) - tsoil4PCM(:,nsoil_PCM,:))/(mlayer(nsoil_PCM + 1) - mlayer(nsoil_PCM))
411
412END SUBROUTINE build4PCM_soil
413!=======================================================================
414
[3989]415END MODULE soil
Note: See TracBrowser for help on using the repository browser.