Skip to content

Commit 85ef371

Browse files
authored
Merge pull request #368 from mvertens/feature/escomp_merge_of_cdeps1.0.83_noresm_v3
bugfix for reading in multi-level unstructured data plus additional cleanup ### Description of changes This PR fixes a CDEPS bug that was found using stream input ne16pg3 with 58 vertical levels using NorESM. CDEPS aborted trying to read this in. ### Specific notes This PR also does the following: - new error checking for most allocations - cleanup of stdout formatting - replacement of` character(*) with character(len=*)` - introduction `logunit `and `mainproc` in shr_strdata_type and both `logunit` and `mainproc` in shr_stream_streamType. This is needed since the inline interface was not always writing all log output consistently. - new expanded API for setting stream pointers with optional arguments in `dshr_strdata_mod.F90` for shr_strdata_get_stream_pointer_1d and shr_strdata_get_stream_pointer_2d ``` subroutine shr_strdata_get_stream_pointer_1d(sdat, strm_fld, strm_ptr, rc, requirePointer, errmsg) type(shr_strdata_type) , intent(in) :: sdat character(len=*) , intent(in) :: strm_fld real(r8) , pointer :: strm_ptr(:) integer , intent(out) :: rc logical, optional , intent(in) :: requirePointer character(len=*), optional , intent(in) :: errmsg ``` and ``` subroutine shr_strdata_get_stream_pointer_2d(sdat, strm_fld, strm_ptr, rc, requirePointer, errmsg) type(shr_strdata_type) , intent(in) :: sdat character(len=*) , intent(in) :: strm_fld real(r8) , pointer :: strm_ptr(:,:) integer , intent(out) :: rc logical, optional , intent(in) :: requirePointer character(len=*), optional , intent(in) :: errmsg ``` If requirePointer is not provided - then if the pointer is not found, the subroutine returns without an error. If requirePointer is an argument and is true, than normally an errmsg is provided that describes why the pointer is required. Also - now if the pointer is required and is found - then the pointer is initialized to NaN. The new setting of NaNs in the stream and state pointers resulted in the following additional changes that needed to be brought in: - refactored dlnd code to remove presence of present nans in stream pointers - fixed problem in drof that came up due to presence of presence of nans - fixed problem in datm/cplhist that cam up due to presence of nans Contributors other than yourself, if any: None CDEPS Issues Fixed: Are there dependencies on other component PRs: None Are changes expected to change answers (bfb, different to roundoff, more substantial): bfb Any User Interface Changes (namelist or namelist defaults changes): None
2 parents e43e829 + 091e808 commit 85ef371

File tree

10 files changed

+1265
-739
lines changed

10 files changed

+1265
-739
lines changed

cime_config/stream_cdeps.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -716,11 +716,11 @@ def _sub_paths(
716716
date_string = (year_format + "-{:02d}-{:02d}").format(
717717
adjusted_year, adjusted_month, adjusted_day
718718
)
719-
new_file = line.replace(match.group(0), date_string)
720-
if os.path.exists(new_file):
721-
new_lines.append(new_file)
719+
new_line = line.replace(match.group(0), date_string)
720+
if os.path.exists(new_line):
721+
new_lines.append(new_line)
722722
else:
723-
print(f" WARNING:not adding missing file {new_file}")
723+
print(f" WARNING:not adding missing file {new_line}")
724724
elif match.group("month"):
725725
for month in range(1, 13):
726726
date_string = (year_format + "-{:02d}").format(year, month)

datm/datm_datamode_cplhist_mod.F90

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@ module datm_datamode_cplhist_mod
2424
real(r8), pointer :: Sa_tbot(:) => null()
2525
real(r8), pointer :: Sa_ptem(:) => null()
2626
real(r8), pointer :: Sa_shum(:) => null()
27-
! TODO: water isotope support
28-
! real(r8), pointer :: Sa_shum_wiso(:,:) => null() ! water isotopes
2927
real(r8), pointer :: Sa_dens(:) => null()
3028
real(r8), pointer :: Sa_pbot(:) => null()
3129
real(r8), pointer :: Sa_pslv(:) => null()
@@ -38,7 +36,6 @@ module datm_datamode_cplhist_mod
3836
real(r8), pointer :: Faxa_swndf(:) => null()
3937
real(r8), pointer :: Faxa_swvdr(:) => null()
4038
real(r8), pointer :: Faxa_swvdf(:) => null()
41-
real(r8), pointer :: Faxa_swnet(:) => null()
4239
real(r8), pointer :: Faxa_ndep(:,:) => null()
4340

4441
character(*), parameter :: nullstr = 'null'
@@ -87,7 +84,6 @@ subroutine datm_datamode_cplhist_advertise(exportState, fldsexport, flds_scalar_
8784
call dshr_fldList_add(fldsExport, 'Faxa_swvdr' )
8885
call dshr_fldList_add(fldsExport, 'Faxa_swndf' )
8986
call dshr_fldList_add(fldsExport, 'Faxa_swvdf' )
90-
call dshr_fldList_add(fldsExport, 'Faxa_swnet' )
9187
call dshr_fldList_add(fldsExport, 'Faxa_lwdn' )
9288
call dshr_fldList_add(fldsExport, 'Faxa_swdn' )
9389
if (flds_co2) then
@@ -172,8 +168,6 @@ subroutine datm_datamode_cplhist_init_pointers(importState, exportState, sdat, r
172168
if (ChkErr(rc,__LINE__,u_FILE_u)) return
173169
call dshr_state_getfldptr(exportState, 'Faxa_swndf' , fldptr1=Faxa_swndf , rc=rc)
174170
if (ChkErr(rc,__LINE__,u_FILE_u)) return
175-
call dshr_state_getfldptr(exportState, 'Faxa_swnet' , fldptr1=Faxa_swnet , rc=rc)
176-
if (ChkErr(rc,__LINE__,u_FILE_u)) return
177171
call dshr_state_getfldptr(exportState, 'Faxa_lwdn' , fldptr1=Faxa_lwdn , rc=rc)
178172
if (ChkErr(rc,__LINE__,u_FILE_u)) return
179173

dlnd/dlnd_datamode_glc_forcing_mod.F90

Lines changed: 82 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ module dlnd_datamode_glc_forcing_mod
55
use NUOPC , only : NUOPC_CompAttributeGet, NUOPC_Advertise
66
use shr_kind_mod , only : r8=>shr_kind_r8, i8=>shr_kind_i8, cl=>shr_kind_cl, cs=>shr_kind_cs
77
use shr_log_mod , only : shr_log_error
8+
use shr_const_mod , only : SHR_CONST_SPVAL
89
use dshr_methods_mod , only : dshr_state_getfldptr, chkerr
9-
use dshr_strdata_mod , only : shr_strdata_type
10+
use dshr_strdata_mod , only : shr_strdata_type, shr_strdata_get_stream_pointer
1011
use dshr_fldlist_mod , only : fldlist_type, dshr_fldlist_add
11-
use dshr_dfield_mod , only : dfield_type, dshr_dfield_add
1212
use glc_elevclass_mod, only : glc_elevclass_as_string, glc_elevclass_init
1313

1414
implicit none
@@ -18,8 +18,19 @@ module dlnd_datamode_glc_forcing_mod
1818
public :: dlnd_datamode_glc_forcing_init_pointers
1919
public :: dlnd_datamode_glc_forcing_advance
2020

21-
! module pointer arrays
22-
real(r8), pointer :: lfrac(:)
21+
! export state pointer
22+
real(r8), pointer :: lfrac(:) => null()
23+
real(r8), pointer :: Sl_tsrf_elev(:,:) => null()
24+
real(r8), pointer :: Sl_topo_elev(:,:) => null()
25+
real(r8), pointer :: Flgl_qice_elev(:,:) => null()
26+
27+
! stream pointers (1d)
28+
type, public :: stream_pointer_type
29+
real(r8), pointer :: strm_ptr(:) => null()
30+
end type stream_pointer_type
31+
type(stream_pointer_type), allocatable :: strm_Sl_tsrf_elev(:)
32+
type(stream_pointer_type), allocatable :: strm_Sl_topo_elev(:)
33+
type(stream_pointer_type), allocatable :: strm_Flgl_qice_elev(:)
2334

2435
integer :: glc_nec
2536

@@ -31,7 +42,8 @@ module dlnd_datamode_glc_forcing_mod
3142
contains
3243
!===============================================================================
3344

34-
subroutine dlnd_datamode_glc_forcing_advertise(gcomp, exportState, fldsExport, flds_scalar_name, logunit, mainproc, rc)
45+
subroutine dlnd_datamode_glc_forcing_advertise(gcomp, exportState, fldsExport, flds_scalar_name, &
46+
logunit, mainproc, rc)
3547

3648
! determine export state to advertise to mediator
3749

@@ -87,24 +99,20 @@ subroutine dlnd_datamode_glc_forcing_advertise(gcomp, exportState, fldsExport, f
8799
end subroutine dlnd_datamode_glc_forcing_advertise
88100

89101
!===============================================================================
90-
subroutine dlnd_datamode_glc_forcing_init_pointers(exportState, sdat, dfields, model_frac, datamode, logunit, mainproc, rc)
102+
subroutine dlnd_datamode_glc_forcing_init_pointers(exportState, sdat, model_frac, datamode, rc)
91103

92104
! input/output variables
93105
type(ESMF_State) , intent(inout) :: exportState
94106
type(shr_strdata_type), intent(in) :: sdat
95-
type(dfield_type) , pointer :: dfields
96107
real(r8) , intent(in) :: model_frac(:)
97108
character(len=*) , intent(in) :: datamode
98-
integer , intent(in) :: logunit
99-
logical , intent(in) :: mainproc
100109
integer , intent(out) :: rc
101110

102111
! local variables
103-
integer :: n
104-
character(len=2) :: nec_str
105-
character(CS), allocatable :: strm_flds_topo(:)
106-
character(CS), allocatable :: strm_flds_tsrf(:)
107-
character(CS), allocatable :: strm_flds_qice(:)
112+
integer :: ng
113+
character(len=2) :: nec_str
114+
character(CS) :: strm_fld
115+
integer :: istat
108116
character(len=*), parameter :: subname='(dlnd_datamode_glc_forcing_init_pointers): '
109117
!-------------------------------------------------------------------------------
110118

@@ -114,87 +122,84 @@ subroutine dlnd_datamode_glc_forcing_init_pointers(exportState, sdat, dfields, m
114122
call dshr_state_getfldptr(exportState, fldname='Sl_lfrin', fldptr1=lfrac, rc=rc)
115123
if (chkerr(rc,__LINE__,u_FILE_u)) return
116124
lfrac(:) = model_frac(:)
125+
call dshr_state_getfldptr(exportState, 'Sl_tsrf_elev', fldptr2=Sl_tsrf_elev, rc=rc)
126+
if (chkerr(rc,__LINE__,u_FILE_u)) return
127+
call dshr_state_getfldptr(exportState, 'Sl_topo_elev', fldptr2=Sl_topo_elev, rc=rc)
128+
if (chkerr(rc,__LINE__,u_FILE_u)) return
129+
call dshr_state_getfldptr(exportState, 'Flgl_qice_elev', fldptr2=Flgl_qice_elev, rc=rc)
130+
if (chkerr(rc,__LINE__,u_FILE_u)) return
117131

118-
! Create stream-> export state mapping
119-
! Note that strm_flds is the model name for the stream field
120-
! Note that state_fld is the model name for the export field
121-
122-
if (trim(datamode) == 'glc_forcing_mct') then
123-
allocate(strm_flds_tsrf(0:glc_nec))
124-
allocate(strm_flds_topo(0:glc_nec))
125-
allocate(strm_flds_qice(0:glc_nec))
126-
do n = 0,glc_nec
127-
write(nec_str, '(i2.2)') n
128-
strm_flds_tsrf(n) = 'Sl_tsrf_elev' // trim(nec_str)
129-
strm_flds_topo(n) = 'Sl_topo_elev' // trim(nec_str)
130-
strm_flds_qice(n) = 'Flgl_qice_elev' // trim(nec_str)
131-
end do
132+
! Obtain pointers to stream fields
132133

133-
else if (trim(datamode) == 'glc_forcing' ) then
134-
allocate(strm_flds_tsrf(1:glc_nec+1))
135-
allocate(strm_flds_topo(1:glc_nec+1))
136-
allocate(strm_flds_qice(1:glc_nec+1))
137-
do n = 1,glc_nec+1
138-
write(nec_str, '(i0)') n
139-
strm_flds_tsrf(n) = 'Sl_tsrf_elev' // trim(nec_str)
140-
strm_flds_topo(n) = 'Sl_topo_elev' // trim(nec_str)
141-
strm_flds_qice(n) = 'Flgl_qice_elev' // trim(nec_str)
142-
end do
143-
else
144-
call shr_log_error(subname//'ERROR illegal datamode = '//trim(datamode), rc=rc)
134+
allocate(strm_Sl_tsrf_elev(glc_nec+1), &
135+
strm_Sl_topo_elev(glc_nec+1), &
136+
strm_Flgl_qice_elev(glc_nec+1), stat=istat)
137+
if ( istat /= 0 ) then
138+
call shr_log_error(subName//&
139+
': allocation error for strm_Sl_tsrf_elev, Strm_Sl_topo_elev and strm_Flgl_qice_elev',rc=rc)
145140
return
146141
end if
147142

148-
! The following maps stream input fields to export fields that have an ungridded dimension
149-
call dshr_dfield_add(dfields, sdat, state_fld='Sl_tsrf_elev', strm_flds=strm_flds_tsrf, state=exportState, &
150-
logunit=logunit, mainproc=mainproc, rc=rc)
151-
if (ChkErr(rc,__LINE__,u_FILE_u)) return
152-
call dshr_dfield_add(dfields, sdat, state_fld='Sl_topo_elev', strm_flds=strm_flds_topo, state=exportState, &
153-
logunit=logunit, mainproc=mainproc, rc=rc)
154-
if (ChkErr(rc,__LINE__,u_FILE_u)) return
155-
call dshr_dfield_add(dfields, sdat, state_fld='Flgl_qice_elev', strm_flds=strm_flds_qice, state=exportState, &
156-
logunit=logunit, mainproc=mainproc, rc=rc)
157-
if (ChkErr(rc,__LINE__,u_FILE_u)) return
143+
do ng = 1,glc_nec+1
144+
if (trim(datamode) == 'glc_forcing_mct') then
145+
write(nec_str,'(i2.2)') ng-1
146+
else
147+
write(nec_str,'(i0)') ng
148+
end if
149+
strm_fld = 'Sl_tsrf_elev'//trim(nec_str)
150+
call shr_strdata_get_stream_pointer( sdat, trim(strm_fld), strm_Sl_tsrf_elev(ng)%strm_ptr, requirePointer=.true., &
151+
errmsg=trim(subname)//'ERROR: '//trim(strm_fld)//' must be associated for dlnd glc_forcing datamode', rc=rc)
152+
if (ChkErr(rc,__LINE__,u_FILE_u)) return
158153

159-
deallocate(strm_flds_tsrf)
160-
deallocate(strm_flds_topo)
161-
deallocate(strm_flds_qice)
154+
strm_fld = 'Sl_topo_elev'//trim(nec_str)
155+
call shr_strdata_get_stream_pointer( sdat, trim(strm_fld), strm_Sl_topo_elev(ng)%strm_ptr, requirePointer=.true., &
156+
errmsg=trim(subname)//'ERROR: '//trim(strm_fld)//' must be associated for dlnd glc_forcing datamode', rc=rc)
157+
if (ChkErr(rc,__LINE__,u_FILE_u)) return
158+
159+
strm_fld = 'Flgl_qice_elev'//trim(nec_str)
160+
call shr_strdata_get_stream_pointer( sdat, trim(strm_fld), strm_Flgl_qice_elev(ng)%strm_ptr, requirePointer=.true., &
161+
errmsg=trim(subname)//'ERROR: '//trim(strm_fld)//' must be associated for dlnd glc_forcing datamode', rc=rc)
162+
if (ChkErr(rc,__LINE__,u_FILE_u)) return
163+
end do
162164

163165
end subroutine dlnd_datamode_glc_forcing_init_pointers
164166

165167
!===============================================================================
166-
subroutine dlnd_datamode_glc_forcing_advance(exportState, rc)
167-
168-
! input/output variables
169-
type(ESMF_State) , intent(inout) :: exportState
170-
integer , intent(out) :: rc
168+
subroutine dlnd_datamode_glc_forcing_advance()
171169

172170
! local variables
173-
integer :: n
174-
real(r8), pointer :: fldptr2(:,:)
171+
integer :: ni,ng
175172
character(len=*), parameter :: subname='(dlnd_datamode_glc_forcing_advance): '
176173
!-------------------------------------------------------------------------------
177174

178-
rc = ESMF_SUCCESS
179-
180175
! Set special value over masked points
181-
call dshr_state_getfldptr(exportState, 'Sl_tsrf_elev', fldptr2=fldptr2, rc=rc)
182-
if (chkerr(rc,__LINE__,u_FILE_u)) return
183-
do n = 1,size(fldptr2,dim=2)
184-
if (lfrac(n) == 0._r8) fldptr2(:,n) = 1.e30_r8
185-
end do
176+
! Note that the inner dimension is the elevation class
177+
178+
elev_class_loop: do ng = 1,glc_nec+1
179+
do ni = 1,size(Sl_tsrf_elev,dim=2)
180+
if (lfrac(ni) == 0._r8) then
181+
Sl_tsrf_elev(ng,ni) = SHR_CONST_SPVAL
182+
else
183+
Sl_tsrf_elev(ng,ni) = strm_Sl_tsrf_elev(ng)%strm_ptr(ni)
184+
end if
185+
end do
186186

187-
call dshr_state_getfldptr(exportState, 'Sl_topo_elev', fldptr2=fldptr2, rc=rc)
188-
if (chkerr(rc,__LINE__,u_FILE_u)) return
189-
do n = 1,size(fldptr2,dim=2)
190-
if (lfrac(n) == 0._r8) fldptr2(:,n) = 1.e30_r8
191-
end do
187+
do ni = 1,size(Sl_topo_elev,dim=2)
188+
if (lfrac(ni) == 0._r8) then
189+
Sl_topo_elev(ng,ni) = SHR_CONST_SPVAL
190+
else
191+
Sl_topo_elev(ng,ni) = strm_Sl_topo_elev(ng)%strm_ptr(ni)
192+
end if
193+
end do
192194

193-
call dshr_state_getfldptr(exportState, 'Flgl_qice_elev', fldptr2=fldptr2, rc=rc)
194-
if (chkerr(rc,__LINE__,u_FILE_u)) return
195-
do n = 1,size(fldptr2,dim=2)
196-
if (lfrac(n) == 0._r8) fldptr2(:,n) = 1.e30_r8
197-
end do
195+
do ni = 1,size(Flgl_qice_elev,dim=2)
196+
if (lfrac(ni) == 0._r8) then
197+
Flgl_qice_elev(ng,ni) = SHR_CONST_SPVAL
198+
else
199+
Flgl_qice_elev(ng,ni) = strm_Flgl_qice_elev(ng)%strm_ptr(ni)
200+
end if
201+
end do
202+
end do elev_class_loop
198203

199204
end subroutine dlnd_datamode_glc_forcing_advance
200205

0 commit comments

Comments
 (0)