@@ -14,7 +14,8 @@ module initVerticalMod
1414 use spmdMod , only : masterproc
1515 use elm_varpar , only : more_vertlayers, nlevsno, nlevgrnd, nlevlak
1616 use elm_varpar , only : toplev_equalspace, nlev_equalspace
17- use elm_varpar , only : nlevsoi, nlevsoifl, nlevurb, nlevslp
17+ use elm_varpar , only : nlevsoi, nlevsoifl, nlevurb, nlevslp
18+ use elm_varpar , only : nlevdecomp, scalez, zecoeff
1819 use elm_varctl , only : fsurdat, iulog, use_var_soil_thick
1920 use elm_varctl , only : use_vancouver, use_mexicocity, use_vertsoilc, use_extralakelayers, use_extrasnowlayers
2021 use elm_varctl , only : use_erosion, use_polygonal_tundra
@@ -26,7 +27,7 @@ module initVerticalMod
2627 use ColumnType , only : col_pp
2728 use ColumnDataType , only : col_ws
2829 use SnowHydrologyMod, only : InitSnowLayers
29- use ncdio_pio
30+ use ncdio_pio , only : file_desc_t, ncd_io, ncd_pio_openfile, ncd_pio_closefile , ncd_inqdlen
3031 use topounit_varcon , only : max_topounits
3132 use GridcellType , only : grc_pp
3233 !
@@ -50,12 +51,16 @@ subroutine initVertical(bounds, snow_depth, thick_wall, thick_roof)
5051 real (r8 ) , intent (in ) :: thick_wall(bounds% begl:)
5152 real (r8 ) , intent (in ) :: thick_roof(bounds% begl:)
5253 !
53- ! LOCAL VARAIBLES:
54- integer :: c,l,t,ti,topi,g,i,j,lev ! indices
54+ ! LOCAL PARAMETERS
55+ integer , parameter :: ndtbname = 2 ! Number of names to try for depth to bedrock
56+ !
57+ ! LOCAL VARIABLES:
58+ integer :: c,l,t,ti,topi,g,i,j,lev,n ! indices
5559 type (file_desc_t) :: ncid ! netcdf id
56- logical :: readvar
60+ logical :: readvar ! Flag: variable was successfully read
5761 integer :: dimid ! dimension id
5862 character (len= 256 ) :: locfn ! local filename
63+ real (r8 ) ,pointer :: zsoi_in(:) ! read in - soil information
5964 real (r8 ) ,pointer :: std (:) ! read in - topo_std
6065 real (r8 ) ,pointer :: tslope (:) ! read in - topo_slope
6166 real (r8 ) ,pointer :: gradz(:) ! read in - gradz (polygonal tundra only)
@@ -68,7 +73,6 @@ subroutine initVertical(bounds, snow_depth, thick_wall, thick_roof)
6873 real (r8 ) :: slopebeta ! temporary
6974 real (r8 ) :: slopemax ! temporary
7075 integer :: ier ! error status
71- real (r8 ) :: scalez = 0.025_r8 ! Soil layer thickness discretization (m)
7276 real (r8 ) :: thick_equal = 0.2
7377 real (r8 ) ,pointer :: lakedepth_in(:,:) ! read in - lakedepth
7478 real (r8 ), allocatable :: zurb_wall(:,:) ! wall (layer node depth)
@@ -80,6 +84,7 @@ subroutine initVertical(bounds, snow_depth, thick_wall, thick_roof)
8084 real (r8 ) :: depthratio ! ratio of lake depth to standard deep lake depth
8185 integer :: begc, endc
8286 integer :: begl, endl
87+ character (len= 256 ), dimension (ndtbname) :: dtbname ! List of possible names for depth to bedrock
8388 !- -----------------------------------------------------------------------
8489
8590 begc = bounds% begc; endc= bounds% endc
@@ -95,47 +100,81 @@ subroutine initVertical(bounds, snow_depth, thick_wall, thick_roof)
95100 call ncd_pio_openfile (ncid, locfn, 0 )
96101
97102 call ncd_inqdlen(ncid, dimid, nlevsoifl, name= ' nlevsoi' )
98- if ( .not. more_vertlayers )then
99- if ( nlevsoifl /= nlevsoi )then
100- call shr_sys_abort(' ERROR: Number of soil layers on file does NOT match the number being used' // &
103+
104+
105+ if ( .not. more_vertlayers ) then
106+ ! Removed the requirement for nlevsoifl to match nlevsoi, but we make sure the
107+ ! number of input layers do not exceed the maximum allocated, to avoid segmentation
108+ ! violation errors.
109+ if ( nlevsoifl > nlevgrnd ) then
110+ call shr_sys_abort(' ERROR: Number of soil layers on file exceeds the maximum number of layers allowed (nlevgrnd)' // &
101111 errMsg(__FILE__, __LINE__))
112+ elseif ( nlevsoifl /= nlevsoi ) then
113+ ! Surface file has a different number of soil levels, update the simulation to
114+ ! match the surface file.
115+ nlevsoi = nlevsoifl
116+ if (use_vertsoilc) nlevdecomp = nlevsoifl
102117 end if
103118 else
104119 ! read in layers, interpolate to high resolution grid later
105120 end if
106121
107122 ! --------------------------------------------------------------------
108- ! Define layer structure for soil, lakes, urban walls and roof
109- ! Vertical profile of snow is not initialized here - but below
110- ! --------------------------------------------------------------------
111-
112- ! Soil layers and interfaces (assumed same for all non-lake patches)
123+ ! Define layer structure for soil, lakes, urban walls and roof. We first check
124+ ! whether or not soil layers exist in the surfacefile. If so, we use the layers from
125+ ! the file. Otherwise, we define the layers using the default parameters, but
126+ ! further checking if the run should include intermediate layers with equal
127+ ! thicknesses.
128+ ! In soil layers and interfaces (assumed same for all non-lake patches),
113129 ! "0" refers to soil surface and "nlevsoi" refers to the bottom of model soil
114-
115- if ( more_vertlayers )then
130+ !
131+ ! Note: vertical profile of snow is not initialized here - but below
132+ ! --------------------------------------------------------------------
133+ ! Try to read soil information from the file.
134+ allocate (zsoi_in(nlevsoi))
135+ call ncd_io(ncid= ncid, varname= ' ZSOI' , flag= ' read' , data = zsoi_in, dim1name= grlnd, readvar= readvar)
136+ if ( readvar ) then
137+ ! -----------------------------------------------------------------
138+ ! File contains soil information. We must complete the soil depth information for
139+ ! layers beneath nlevsoi, using the original scaling parameters for increasing the
140+ ! depth of the layers, but acknowledging that the layer must be beneath the deepest
141+ ! input soil layer.
142+ ! -----------------------------------------------------------------
143+ zsoi(1 :nlevsoi) = zsoi_in(1 :nlevsoi)
144+ do j = nlevsoi+1 , nlevgrnd
145+ zsoi(j) = zsoi(nlevsoi) + &
146+ scalez* (exp (zecoeff* (j - 0.5_r8 ))- exp (zecoeff* (nlevsoi-0.5_r8 )))
147+ end do
148+
149+
150+ elseif ( more_vertlayers )then
116151 ! replace standard exponential grid with a grid that starts out exponential,
117152 ! then has several evenly spaced layers, then finishes off exponential.
118153 ! this allows the upper soil to behave as standard, but then continues
119154 ! with higher resolution to a deeper depth, so that, for example, permafrost
120155 ! dynamics are not lost due to an inability to resolve temperature, moisture,
121156 ! and biogeochemical dynamics at the base of the active layer
122157 do j = 1 , toplev_equalspace
123- zsoi(j) = scalez* (exp (0.5_r8 * (j-0.5_r8 ))- 1._r8 ) ! node depths
158+ zsoi(j) = scalez* (exp (zecoeff * (j-0.5_r8 ))- 1._r8 ) ! node depths
124159 enddo
125160
126161 do j = toplev_equalspace+1 ,toplev_equalspace + nlev_equalspace
127162 zsoi(j) = zsoi(j-1 ) + thick_equal
128163 enddo
129164
130165 do j = toplev_equalspace + nlev_equalspace + 1 , nlevgrnd
131- zsoi(j) = scalez* (exp (0.5_r8 * ((j - nlev_equalspace)- 0.5_r8 ))- 1._r8 ) + nlev_equalspace * thick_equal
166+ zsoi(j) = scalez* (exp (zecoeff * ((j - nlev_equalspace)- 0.5_r8 ))- 1._r8 ) + nlev_equalspace * thick_equal
132167 enddo
133168 else
134-
169+ ! -----------------------------------------------------------------
170+ ! Soil layers not available from the input, and no additional layers needed. Use the
171+ ! default soil thickness settings.
172+ ! -----------------------------------------------------------------
135173 do j = 1 , nlevgrnd
136- zsoi(j) = scalez* (exp (0.5_r8 * (j-0.5_r8 ))- 1._r8 ) ! node depths
174+ zsoi(j) = scalez* (exp (zecoeff * (j-0.5_r8 ))- 1._r8 ) ! node depths
137175 enddo
138176 end if
177+ deallocate (zsoi_in)
139178
140179 dzsoi(1 ) = 0.5_r8 * (zsoi(1 )+ zsoi(2 )) ! thickness b/n two interfaces
141180 do j = 2 ,nlevgrnd-1
@@ -629,9 +668,22 @@ subroutine initVertical(bounds, snow_depth, thick_wall, thick_roof)
629668
630669 if (use_var_soil_thick) then
631670 allocate (dtb(bounds% begg:bounds% endg,1 :max_topounits))
632- call ncd_io(ncid= ncid, varname= ' aveDTB' , flag= ' read' , data = dtb, dim1name= grlnd, readvar= readvar)
671+
672+ ! ELM and CLM use different names for depth to bedrock in the surface file
673+ ! ('aveDTB' and 'zbedrock', respectively). To keep cross-model compatibility, we
674+ ! test both names before falling back to the default number of layers.
675+ dtbname(1 ) = ' aveDTB'
676+ dtbname(2 ) = ' zbedrock'
677+ readvar = .false.
678+ do n= 1 ,ndtbname
679+ if (.not. readvar) then
680+ call ncd_io(ncid= ncid, varname= dtbname(n), flag= ' read' , data = dtb, dim1name= grlnd, readvar= readvar)
681+ end if
682+ end do
683+
684+
633685 if (.not. readvar) then
634- write (iulog,* ) ' aveDTB not in surfdata: reverting to default 10 layers.'
686+ write (iulog,fmt = ' (a,i5,a) ' ) ' aveDTB not in surfdata: reverting to default ' ,nlevsoi, ' layers.'
635687 do c = begc,endc
636688 col_pp% nlevbed(c) = nlevsoi
637689 col_pp% zibed(c) = zisoi(nlevsoi)
0 commit comments