Skip to content

Commit 5b3f120

Browse files
Adds the ability to read a CDEPS configuration file to provide in-line forcing.
* Adds the ability to read a CDEPS configuration file to provide in-line forcing. Currently this is set up to read a non-climatological lrunoff data stream only.
1 parent 41f39db commit 5b3f120

2 files changed

Lines changed: 241 additions & 0 deletions

File tree

config_src/drivers/nuopc_cap/mom_cap.F90

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ module MOM_cap_mod
9393
use NUOPC_Model, only: model_label_Finalize => label_Finalize
9494
use NUOPC_Model, only: SetVM
9595

96+
use mom_inline_mod, only : mom_inline_init, mom_inline_run
9697
#ifndef CESMCOUPLED
9798
use shr_is_restart_fh_mod, only : init_is_restart_fh, is_restart_fh, is_restart_fh_type
9899
#endif
@@ -144,6 +145,7 @@ module MOM_cap_mod
144145
logical :: use_mommesh = .true.
145146
logical :: set_missing_stks_to_zero = .false.
146147
logical :: restart_eor = .false.
148+
logical :: use_cdeps_inline = .false.
147149
character(len=128) :: scalar_field_name = ''
148150
integer :: scalar_field_count = 0
149151
integer :: scalar_field_idx_grid_nx = 0
@@ -397,6 +399,14 @@ subroutine InitializeP0(gcomp, importState, exportState, clock, rc)
397399
geomtype = ESMF_GEOMTYPE_GRID
398400
endif
399401

402+
use_cdeps_inline = .false.
403+
call NUOPC_CompAttributeGet(gcomp, name="use_cdeps_inline", value=value, &
404+
isPresent=isPresent, isSet=isSet, rc=rc)
405+
if (ChkErr(rc,__LINE__,u_FILE_u)) return
406+
if (isPresent .and. isSet) use_cdeps_inline=(trim(value)=="true")
407+
write(logmsg,*) use_cdeps_inline
408+
call ESMF_LogWrite('MOM_cap:use_cdeps_inline = '//trim(logmsg), ESMF_LOGMSG_INFO)
409+
400410
! Read end of run restart config option
401411
call NUOPC_CompAttributeGet(gcomp, name="write_restart_at_endofrun", value=value, &
402412
isPresent=isPresent, isSet=isSet, rc=rc)
@@ -1584,6 +1594,11 @@ subroutine InitializeRealize(gcomp, importState, exportState, clock, rc)
15841594
!---------------------------------
15851595
call mom_set_geomtype(geomtype)
15861596

1597+
if (use_cdeps_inline) then
1598+
call mom_inline_init(gcomp, clock, eMesh, localPet, rc=rc)
1599+
if (ChkErr(rc,__LINE__,u_FILE_u)) return
1600+
end if
1601+
15871602
!---------------------------------
15881603
! write out diagnostics
15891604
!---------------------------------
@@ -1861,6 +1876,11 @@ subroutine ModelAdvance(gcomp, rc)
18611876
set_missing_stks_to_zero, rc=rc)
18621877
if (ChkErr(rc,__LINE__,u_FILE_u)) return
18631878

1879+
if (use_cdeps_inline) then
1880+
call mom_inline_run(clock, ocean_public, ocean_grid, ice_ocean_boundary, dbug, rc=rc)
1881+
if (ChkErr(rc,__LINE__,u_FILE_u)) return
1882+
end if
1883+
18641884
!---------------
18651885
! Update MOM6
18661886
!---------------
Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
module mom_inline_mod
2+
3+
use NUOPC , only: NUOPC_CompAttributeGet
4+
use ESMF , only: ESMF_GridComp, ESMF_Mesh
5+
use ESMF , only: ESMF_Clock, ESMF_Time, ESMF_TimeGet, ESMF_ClockGet
6+
use ESMF , only: ESMF_KIND_R8, ESMF_SUCCESS, ESMF_LogFoundError
7+
use ESMF , only: ESMF_LOGERR_PASSTHRU, ESMF_LOGMSG_INFO, ESMF_LOGWRITE
8+
use ESMF , only: ESMF_END_ABORT, ESMF_Finalize, ESMF_MAXSTR
9+
use dshr_mod , only: dshr_pio_init
10+
use dshr_strdata_mod , only: shr_strdata_type, shr_strdata_print
11+
use dshr_strdata_mod , only: shr_strdata_init_from_inline
12+
use dshr_strdata_mod , only: shr_strdata_advance
13+
use dshr_methods_mod , only: dshr_fldbun_getfldptr, dshr_fldbun_Field_diagnose
14+
use dshr_stream_mod , only: shr_stream_init_from_esmfconfig
15+
use MOM_cap_methods , only: ChkErr
16+
17+
implicit none
18+
private
19+
20+
public mom_inline_init
21+
public mom_inline_run
22+
23+
type(shr_strdata_type), allocatable :: sdat(:)
24+
25+
integer :: logunit ! the logunit on the root task
26+
character(len=ESMF_MAXSTR) :: stream_name ! generic identifier
27+
28+
character(len=*), parameter :: u_FILE_u = __FILE__
29+
contains
30+
!===============================================================================
31+
subroutine mom_inline_init(gcomp, model_clock, model_mesh, mytask, rc)
32+
33+
! input/output parameters
34+
type(ESMF_GridComp) , intent(in) :: gcomp !< ESMF_GridComp object
35+
type(ESMF_Clock) , intent(in) :: model_clock !< ESMF_Clock object
36+
type(ESMF_Mesh) , intent(in) :: model_mesh !< ESMF mesh
37+
integer , intent(in) :: mytask !< the current task
38+
integer , intent(out) :: rc !< Return code
39+
40+
! stream data from config (xml or esmf), one or more streams
41+
type(shr_strdata_type) :: sdatconfig
42+
43+
! local variables
44+
logical :: isPresent, isSet
45+
integer :: ns, l
46+
integer :: nstreams, nvars
47+
48+
character(len=ESMF_MAXSTR) :: value, streamfilename
49+
character(len=ESMF_MAXSTR), allocatable :: filelist(:)
50+
character(len=ESMF_MAXSTR), allocatable :: filevars(:,:)
51+
52+
character(len=*), parameter :: subname='(mom_inline_init)'
53+
!----------------------------------------------------------------------
54+
55+
rc = ESMF_SUCCESS
56+
57+
call NUOPC_CompAttributeGet(gcomp, name="streamfilename", value=value, isPresent=isPresent, isSet=isSet, rc=rc)
58+
if (ChkErr(rc,__LINE__,u_FILE_u)) return
59+
if (isPresent .and. isSet) then
60+
streamfilename = value
61+
else
62+
call ESMF_LogWrite(trim(subname)//': streamfilename must be provided', ESMF_LOGMSG_INFO)
63+
call ESMF_Finalize(endflag=ESMF_END_ABORT)
64+
return
65+
end if
66+
67+
#ifndef CESMCOUPLED
68+
if (mytask == 0) then
69+
open (newunit=logunit, file='log.mom6.cdeps')
70+
else
71+
logunit = 6
72+
end if
73+
74+
! CMEPS Init PIO
75+
call dshr_pio_init(gcomp, sdatconfig, logunit, rc=rc)
76+
if (chkerr(rc,__LINE__,u_FILE_u)) return
77+
78+
! read the available stream definitions, each data stream is one or more data_files
79+
! which have the same spatial and temporal coordinates
80+
call shr_stream_init_from_esmfconfig(trim(streamfilename), sdatconfig%stream, logunit, &
81+
sdatconfig%pio_subsystem, sdatconfig%io_type, sdatconfig%io_format, rc=rc)
82+
if (chkerr(rc,__LINE__,u_FILE_u)) return
83+
#else
84+
!TODO: CESM logunit, configuration via xml etc
85+
!call shr_stream_init_from_xml(trim(streamfilename) ....
86+
#endif
87+
88+
nstreams = size(sdatconfig%stream)
89+
! allocate stream data type
90+
if (.not. allocated(sdat)) allocate(sdat(nstreams))
91+
92+
! set the model clock and mesh
93+
sdat(:)%model_clock = model_clock
94+
sdat(:)%model_mesh = model_mesh
95+
96+
! loop over streams and initialize
97+
do ns = 1, nstreams
98+
sdat(ns)%pio_subsystem => sdatconfig%pio_subsystem
99+
sdat(ns)%io_type = sdatconfig%io_type
100+
sdat(ns)%io_format = sdatconfig%io_format
101+
102+
allocate(filelist(sdatconfig%stream(ns)%nfiles))
103+
allocate(filevars(sdatconfig%stream(ns)%nvars,2))
104+
105+
! fill stream info
106+
do l = 1, sdatconfig%stream(ns)%nfiles
107+
filelist(l) = trim(sdatconfig%stream(ns)%file(l)%name)
108+
end do
109+
do l = 1, sdatconfig%stream(ns)%nvars
110+
filevars(l,1) = trim(sdatconfig%stream(ns)%varlist(l)%nameinfile)
111+
filevars(l,2) = trim(sdatconfig%stream(ns)%varlist(l)%nameinmodel)
112+
end do
113+
114+
write(stream_name,fmt='(a,i2.2)') 'stream_', ns
115+
call shr_strdata_init_from_inline(sdat(ns), &
116+
my_task = mytask, &
117+
logunit = logunit, &
118+
compname = 'OCN', &
119+
model_clock = sdat(ns)%model_clock, &
120+
model_mesh = sdat(ns)%model_mesh, &
121+
stream_name = trim(stream_name), &
122+
stream_meshfile = trim(sdatconfig%stream(ns)%meshfile), &
123+
stream_filenames = filelist, &
124+
stream_yearFirst = sdatconfig%stream(ns)%yearFirst, &
125+
stream_yearLast = sdatconfig%stream(ns)%yearLast, &
126+
stream_yearAlign = sdatconfig%stream(ns)%yearAlign, &
127+
stream_fldlistFile = filevars(:,1), &
128+
stream_fldListModel = filevars(:,2), &
129+
stream_lev_dimname = trim(sdatconfig%stream(ns)%lev_dimname), &
130+
stream_mapalgo = trim(sdatconfig%stream(ns)%mapalgo), &
131+
stream_offset = sdatconfig%stream(ns)%offset, &
132+
stream_taxmode = trim(sdatconfig%stream(ns)%taxmode), &
133+
stream_dtlimit = sdatconfig%stream(ns)%dtlimit, &
134+
stream_tintalgo = trim(sdatconfig%stream(ns)%tInterpAlgo), &
135+
stream_src_mask = sdatconfig%stream(ns)%src_mask_val, &
136+
stream_dst_mask = sdatconfig%stream(ns)%dst_mask_val, &
137+
rc = rc)
138+
if (chkerr(rc,__LINE__,u_FILE_u)) return
139+
140+
deallocate(filelist)
141+
deallocate(filevars)
142+
end do
143+
144+
end subroutine mom_inline_init
145+
!===============================================================================
146+
subroutine mom_inline_run(clock, ocean_public, ocean_grid, ice_ocean_boundary, dbug, rc)
147+
148+
use MOM_ocean_model_nuopc, only: ocean_public_type
149+
use MOM_surface_forcing_nuopc, only: ice_ocean_boundary_type
150+
use MOM_grid, only: ocean_grid_type
151+
use mpp_domains_mod, only: mpp_get_compute_domain
152+
153+
! input/output variables
154+
type(ESMF_Clock) , intent(in) :: clock !< ESMF_Clock object
155+
type(ocean_public_type) , intent(in) :: ocean_public !< Ocean surface state
156+
type(ocean_grid_type) , intent(in) :: ocean_grid !< Ocean model grid
157+
type(ice_ocean_boundary_type) , intent(inout) :: ice_ocean_boundary !< Ocean boundary forcing
158+
integer , intent(in) :: dbug !< Integer debug flag
159+
integer , intent(out) :: rc !< Return code
160+
161+
! local variables
162+
type(ESMF_Time) :: date
163+
integer :: nstreams, nflds
164+
integer :: ns,nf,n,i,j
165+
integer :: isc, iec, jsc, jec
166+
integer :: year ! year (0, ...) for nstep+1
167+
integer :: mon ! month (1, ..., 12) for nstep+1
168+
integer :: day ! day of month (1, ..., 31) for nstep+1
169+
integer :: sec ! seconds into current date for nstep+1
170+
integer :: mcdate ! Current model date (yyyymmdd)
171+
character(len=ESMF_MAXSTR) :: fldname
172+
real(ESMF_KIND_R8), pointer :: dataPtr1d(:)
173+
character(len=*), parameter :: subname='(mom_inline_run)'
174+
!-----------------------------------------------------------------------
175+
176+
rc = ESMF_SUCCESS
177+
178+
! The following are global indices without halos
179+
call mpp_get_compute_domain(ocean_public%domain, isc, iec, jsc, jec)
180+
181+
! Current model date
182+
call ESMF_ClockGet( clock, currTime=date, rc=rc )
183+
if (chkerr(rc,__LINE__,u_FILE_u)) return
184+
call ESMF_TimeGet(date, yy=year, mm=mon, dd=day, s=sec, rc=rc)
185+
if (chkerr(rc,__LINE__,u_FILE_u)) return
186+
mcdate = year*10000 + mon*100 + day
187+
188+
nstreams = size(sdat)
189+
! Advance the streams
190+
do ns = 1,nstreams
191+
write(stream_name,fmt='(a,i2.2)') 'stream_', ns
192+
call shr_strdata_advance(sdat(ns), ymd=mcdate, tod=sec, logunit=logunit, istr=trim(stream_name),rc=rc)
193+
if (chkerr(rc,__LINE__,u_FILE_u)) return
194+
195+
nflds = size(sdat(ns)%pstrm(1)%fldlist_model)
196+
do nf = 1,nflds
197+
fldname = trim(sdat(ns)%pstrm(1)%fldlist_model(nf))
198+
199+
if (fldname == 'lrunoff') then
200+
! Get pointer for stream data that is time and spatially interpolated to model time and grid
201+
call dshr_fldbun_getFldPtr(sdat(ns)%pstrm(1)%fldbun_model, trim(fldname), dataPtr1d, rc=rc)
202+
if (chkerr(rc,__LINE__,u_FILE_u)) return
203+
204+
n = 0
205+
do j = jsc,jec
206+
do i = isc,iec
207+
n = n + 1
208+
ice_ocean_boundary%lrunoff(i,j) = dataPtr1d(n)
209+
end do
210+
end do
211+
end if
212+
213+
if (dbug > 1) then
214+
call dshr_fldbun_Field_diagnose(sdat(ns)%pstrm(1)%fldbun_model, trim(fldname), 'inline_run ', rc=rc)
215+
if (chkerr(rc,__LINE__,u_FILE_u)) return
216+
end if
217+
end do !nf
218+
end do !ns
219+
220+
end subroutine mom_inline_run
221+
end module mom_inline_mod

0 commit comments

Comments
 (0)