Skip to content

Commit a5bfe2a

Browse files
committed
namelist inputs: parameters_in_file and parameters_in_file_adj
This way, additional memory is only allocated, when parameters are read from file.
1 parent 46ea27e commit a5bfe2a

2 files changed

Lines changed: 122 additions & 52 deletions

File tree

docs/users_guide/introduction/perturbation.md

Lines changed: 71 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -159,20 +159,78 @@ with the `_adj` suffix:
159159
- If adjusted parameters are not present in the surface file, eCLM falls
160160
back to the original parameters or pedotransfer functions
161161

162-
#### Parameter Priority and Fallback Option
163-
164-
The code in `SoilStateInitTimeConstMod.F90` follows this priority order:
165-
166-
1. **First priority**: Read `_adj` parameters (if present) → applies
167-
to all `nlevgrnd` layers → **overwrites** organic matter mixing
168-
results
169-
2. **Second priority**: Read original parameters → applies to first 10
170-
layers (`nlevsoifl`) → undergoes organic matter mixing
171-
3. **Fallback**: Use pedotransfer functions if parameters are absent
172-
from the file
162+
#### Namelist Configuration
163+
164+
The soil hydraulic parameter reading behavior is controlled by two
165+
namelist settings in the `clm_soilstate_inparm` section of the `lnd_in`
166+
namelist file:
167+
168+
##### `parameters_in_file`
169+
170+
**Type:** logical
171+
**Default:** `.false.`
172+
**Description:** Controls whether to read baseline hydraulic parameters
173+
from the surface dataset file.
174+
175+
When set to `.true.`:
176+
- eCLM reads `THETAS`, `SHAPE_PARAM`, `PSIS_SAT`, and `KSAT` from the
177+
surface file
178+
- Parameters apply to the first 10 soil layers (`nlevsoifl=10`)
179+
- Parameters undergo organic matter mixing
180+
- If any required variable is missing, the model aborts with an error
181+
message
182+
183+
When set to `.false.` (default):
184+
- Hydraulic parameters are computed via pedotransfer functions from
185+
sand and clay fractions
186+
- No parameters are read from the surface file
187+
188+
##### `parameters_in_file_adj`
189+
190+
**Type:** logical
191+
**Default:** `.false.`
192+
**Description:** Controls whether to read adjusted hydraulic parameters
193+
from the surface dataset file.
194+
195+
When set to `.true.`:
196+
- eCLM reads `THETAS_adj`, `SHAPE_PARAM_adj`, `PSIS_SAT_adj`, and
197+
`KSAT_adj` from the surface file
198+
- Parameters apply to **all** `nlevgrnd` soil layers (typically 25
199+
layers)
200+
- Adjusted parameters **overwrite** the results from organic matter
201+
mixing
202+
- If any required variable is missing, the model aborts with an error
203+
message
204+
205+
When set to `.false.` (default):
206+
- No adjusted parameters are read from the surface file
207+
- Organic matter mixing results are used as final parameter values
208+
209+
##### Example Configuration
210+
211+
```fortran
212+
&clm_soilstate_inparm
213+
organic_frac_squared = .false.
214+
parameters_in_file = .false.
215+
parameters_in_file_adj = .true.
216+
/
217+
```
173218

174-
This hierarchical approach ensures maximum flexibility for both
175-
standard simulations and data assimilation applications.
219+
This configuration:
220+
- Reads adjusted parameters from the surface file which override the
221+
organic matter mixing results
222+
- Is typical for ensemble data assimilation applications with perturbed
223+
soil parameters
224+
225+
##### Error Handling
226+
227+
Both namelist parameters enforce strict error checking:
228+
- If set to `.true.`, **all** required parameters must be present in
229+
the surface file
230+
- Missing variables trigger an immediate model abort with a descriptive
231+
error message
232+
- This ensures users are explicitly aware when parameter files are
233+
incomplete
176234

177235
#### Note about the Brooks-Corey Shape Parameter ####
178236

src/clm5/biogeophys/SoilStateInitTimeConstMod.F90

Lines changed: 51 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ module SoilStateInitTimeConstMod
2222
! !PRIVATE DATA:
2323
! Control variables (from namelist)
2424
logical, private :: organic_frac_squared ! If organic fraction should be squared (as in CLM4.5)
25+
logical, private :: parameters_in_file ! If soil hydraulic parameters should be read from file
26+
logical, private :: parameters_in_file_adj ! If adjusted soil hydraulic parameters should be read from file
2527

2628
character(len=*), parameter, private :: sourcefile = &
2729
__FILE__
@@ -55,11 +57,14 @@ subroutine ReadNL( nlfilename )
5557

5658
character(len=*), parameter :: nl_name = 'clm_soilstate_inparm' ! Namelist name
5759
! MUST agree with name in namelist and read
58-
namelist / clm_soilstate_inparm / organic_frac_squared
60+
namelist / clm_soilstate_inparm / organic_frac_squared, parameters_in_file, &
61+
parameters_in_file_adj
5962

6063
! preset values
6164

6265
organic_frac_squared = .false.
66+
parameters_in_file = .false.
67+
parameters_in_file_adj = .false.
6368

6469
if ( masterproc )then
6570

@@ -80,6 +85,14 @@ subroutine ReadNL( nlfilename )
8085
end if
8186

8287
call shr_mpi_bcast(organic_frac_squared, mpicom)
88+
call shr_mpi_bcast(parameters_in_file, mpicom)
89+
call shr_mpi_bcast(parameters_in_file_adj, mpicom)
90+
91+
! Check for incompatible namelist settings
92+
if (parameters_in_file .and. parameters_in_file_adj) then
93+
call endrun(msg=' ERROR: parameters_in_file and parameters_in_file_adj cannot both be .true.'//&
94+
errmsg(sourcefile, __LINE__))
95+
end if
8396

8497
end subroutine ReadNL
8598

@@ -167,9 +180,6 @@ subroutine SoilStateInitTimeConst(bounds, soilstate_inst, nlfilename)
167180
integer :: begp, endp
168181
integer :: begc, endc
169182
integer :: begg, endg
170-
! SHP start
171-
logical :: parameters_in_file, parameters_in_file_adj
172-
! SHP end
173183
!-----------------------------------------------------------------------
174184

175185
begp = bounds%begp; endp= bounds%endp
@@ -240,15 +250,19 @@ subroutine SoilStateInitTimeConst(bounds, soilstate_inst, nlfilename)
240250
allocate(sand3d(begg:endg,nlevsoifl))
241251
allocate(clay3d(begg:endg,nlevsoifl))
242252
! SHP start
243-
allocate(thetas(begg:endg,nlevsoifl))
244-
allocate(shape_param(begg:endg,nlevsoifl))
245-
allocate(psis_sat(begg:endg,nlevsoifl))
246-
allocate(ks(begg:endg,nlevsoifl))
247-
248-
allocate(thetas_adj(begg:endg,nlevgrnd))
249-
allocate(shape_param_adj(begg:endg,nlevgrnd))
250-
allocate(psis_sat_adj(begg:endg,nlevgrnd))
251-
allocate(ks_adj(begg:endg,nlevgrnd))
253+
if(parameters_in_file) then
254+
allocate(thetas(begg:endg,nlevsoifl))
255+
allocate(shape_param(begg:endg,nlevsoifl))
256+
allocate(psis_sat(begg:endg,nlevsoifl))
257+
allocate(ks(begg:endg,nlevsoifl))
258+
end if
259+
260+
if(parameters_in_file_adj) then
261+
allocate(thetas_adj(begg:endg,nlevgrnd))
262+
allocate(shape_param_adj(begg:endg,nlevgrnd))
263+
allocate(psis_sat_adj(begg:endg,nlevgrnd))
264+
allocate(ks_adj(begg:endg,nlevgrnd))
265+
end if
252266
! SHP end
253267

254268
! Determine organic_max from parameter file
@@ -279,65 +293,59 @@ subroutine SoilStateInitTimeConst(bounds, soilstate_inst, nlfilename)
279293

280294
call ncd_io(ncid=ncid, varname='PCT_SAND', flag='read', data=sand3d, dim1name=grlnd, readvar=readvar)
281295
if (.not. readvar) then
282-
call endrun(msg=' ERROR: PCT_SAND NOT on surfdata file'//errMsg(sourcefile, __LINE__))
296+
call endrun(msg=' ERROR: PCT_SAND NOT on surfdata file'//errMsg(sourcefile, __LINE__))
283297
end if
284298

285299
call ncd_io(ncid=ncid, varname='PCT_CLAY', flag='read', data=clay3d, dim1name=grlnd, readvar=readvar)
286300
if (.not. readvar) then
287-
call endrun(msg=' ERROR: PCT_CLAY NOT on surfdata file'//errMsg(sourcefile, __LINE__))
301+
call endrun(msg=' ERROR: PCT_CLAY NOT on surfdata file'//errMsg(sourcefile, __LINE__))
288302
end if
289303

290304
! SHP start
291305
! include option to also read hydraulic parameters from file. Keep it variable so that the code also works for surface files that were
292306
! generated without parameter perturbation and parameter as input variables
293307

294-
call ncd_io(ncid=ncid, varname='THETAS', flag='read', data=thetas, dim1name=grlnd, readvar=readvar)
295-
if (.not. readvar) then
296-
parameters_in_file = .False.
297-
else
298-
parameters_in_file = .True.
299-
end if
308+
if (parameters_in_file) then
309+
call ncd_io(ncid=ncid, varname='THETAS', flag='read', data=thetas, dim1name=grlnd, readvar=readvar)
310+
if (.not. readvar) then
311+
call endrun(msg=' ERROR: THETAS NOT on surfdata file'//errMsg(sourcefile, __LINE__))
312+
end if
300313

301-
if (parameters_in_file) then ! read also other paramters, if one of them is not included, use sand and clay to compute parameters
302-
! via pedotransfer function
303314
call ncd_io(ncid=ncid, varname='SHAPE_PARAM', flag='read', data=shape_param, dim1name=grlnd, readvar=readvar)
304315
if (.not. readvar) then
305-
parameters_in_file = .False.
316+
call endrun(msg=' ERROR: SHAPE_PARAM NOT on surfdata file'//errMsg(sourcefile, __LINE__))
306317
end if
307318

308319
call ncd_io(ncid=ncid, varname='PSIS_SAT', flag='read', data=psis_sat, dim1name=grlnd, readvar=readvar)
309320
if (.not. readvar) then
310-
parameters_in_file = .False.
321+
call endrun(msg=' ERROR: PSIS_SAT NOT on surfdata file'//errMsg(sourcefile, __LINE__))
311322
end if
312323

313324
call ncd_io(ncid=ncid, varname='KSAT', flag='read', data=ks, dim1name=grlnd, readvar=readvar)
314325
if (.not. readvar) then
315-
parameters_in_file = .False.
326+
call endrun(msg=' ERROR: KSAT NOT on surfdata file'//errMsg(sourcefile, __LINE__))
316327
end if
317328
end if
318329

319-
call ncd_io(ncid=ncid, varname='THETAS_adj', flag='read', data=thetas_adj, dim1name=grlnd, readvar=readvar)
320-
if (.not. readvar) then
321-
parameters_in_file_adj = .False.
322-
else
323-
parameters_in_file_adj = .True.
324-
end if
330+
if (parameters_in_file_adj) then
331+
call ncd_io(ncid=ncid, varname='THETAS_adj', flag='read', data=thetas_adj, dim1name=grlnd, readvar=readvar)
332+
if (.not. readvar) then
333+
call endrun(msg=' ERROR: THETAS_ADJ NOT on surfdata file'//errMsg(sourcefile, __LINE__))
334+
end if
325335

326-
if (parameters_in_file_adj) then ! read also other paramters, if one of them is not included, use sand and clay to compute parameters
327-
! via pedotransfer function
328336
call ncd_io(ncid=ncid, varname='SHAPE_PARAM_adj', flag='read', data=shape_param_adj, dim1name=grlnd, readvar=readvar)
329337
if (.not. readvar) then
330-
parameters_in_file_adj = .False.
338+
call endrun(msg=' ERROR: SHAPE_PARAM_adj NOT on surfdata file'//errMsg(sourcefile, __LINE__))
331339
end if
332340

333341
call ncd_io(ncid=ncid, varname='PSIS_SAT_adj', flag='read', data=psis_sat_adj, dim1name=grlnd, readvar=readvar)
334342
if (.not. readvar) then
335-
parameters_in_file_adj = .False.
343+
call endrun(msg=' ERROR: PSIS_SAT_adj NOT on surfdata file'//errMsg(sourcefile, __LINE__))
336344
end if
337345

338346
call ncd_io(ncid=ncid, varname='KSAT_adj', flag='read', data=ks_adj, dim1name=grlnd, readvar=readvar)
339347
if (.not. readvar) then
340-
parameters_in_file_adj = .False.
348+
call endrun(msg=' ERROR: KSAT_adj NOT on surfdata file'//errMsg(sourcefile, __LINE__))
341349
end if
342350
end if
343351
! SHP end
@@ -744,8 +752,12 @@ subroutine SoilStateInitTimeConst(bounds, soilstate_inst, nlfilename)
744752
deallocate(sand3d, clay3d, organic3d)
745753
deallocate(zisoifl, zsoifl, dzsoifl)
746754
! SHP start
747-
deallocate(thetas, shape_param, psis_sat, ks)
748-
deallocate(thetas_adj, shape_param_adj, psis_sat_adj, ks_adj)
755+
if(parameters_in_file) then
756+
deallocate(thetas, shape_param, psis_sat, ks)
757+
end if
758+
if(parameters_in_file_adj) then
759+
deallocate(thetas_adj, shape_param_adj, psis_sat_adj, ks_adj)
760+
end if
749761
! SHP end
750762

751763
end subroutine SoilStateInitTimeConst

0 commit comments

Comments
 (0)