Line data Source code
1 : !================================================================================
2 : ! offline unit driver utility module
3 : !
4 : !================================================================================
5 : module offline_driver
6 :
7 : use shr_kind_mod, only: r8=>SHR_KIND_R8, cl=>SHR_KIND_CL
8 : use cam_abortutils, only: endrun
9 : use spmd_utils, only: masterproc
10 : use cam_logfile, only: iulog
11 : use drv_input_data, only: drv_input_data_t
12 : use drv_input_data, only: drv_input_data_open, drv_input_data_close
13 : use tracer_data, only: incr_filename
14 :
15 : implicit none
16 : private
17 : save
18 :
19 : public :: offline_driver_init
20 : public :: offline_driver_run
21 : public :: offline_driver_dorun
22 : public :: offline_driver_readnl
23 : public :: offline_driver_reg
24 :
25 : integer :: recno = 1
26 : logical, protected :: offline_driver_dorun = .false.
27 :
28 : character(len=cl) :: current_file = ' '
29 : character(len=cl) :: next_file = ' '
30 : character(len=cl) :: offline_driver_fileslist = ' '
31 :
32 : type(drv_input_data_t) :: curr_indata
33 :
34 : contains
35 :
36 : !================================================================================
37 : !================================================================================
38 1536 : subroutine offline_driver_reg()
39 : use unit_driver, only: unit_driver_reg
40 1536 : call unit_driver_reg()
41 1536 : end subroutine offline_driver_reg
42 :
43 : !================================================================================
44 : !================================================================================
45 0 : subroutine offline_driver_run( phys_state, pbuf2d, cam_out, cam_in )
46 :
47 : use physics_types, only: physics_state
48 : use ppgrid, only: begchunk, endchunk
49 : use camsrfexch, only: cam_out_t, cam_in_t
50 : use physics_buffer, only: physics_buffer_desc
51 : use time_manager, only: get_curr_date
52 : use unit_driver, only: unit_driver_run
53 :
54 : type(physics_state), intent(inout) :: phys_state(begchunk:endchunk)
55 : type(cam_out_t), intent(inout) :: cam_out(begchunk:endchunk)
56 : type(cam_in_t), intent(inout) :: cam_in(begchunk:endchunk)
57 : type(physics_buffer_desc), pointer :: pbuf2d(:,:)
58 :
59 : integer :: yr, mon, day
60 : integer :: curr_model_date, curr_model_tod
61 : logical :: active_step
62 :
63 0 : if (.not.offline_driver_dorun) return
64 :
65 : ! check model date/time against input data date/time
66 0 : call get_curr_date(yr, mon, day, curr_model_tod)
67 0 : curr_model_date = yr*10000 + mon*100 + day
68 0 : if ( recno <= curr_indata%ntimes ) then
69 0 : active_step = curr_model_date==curr_indata%dates(recno) .and. curr_model_tod==curr_indata%secs(recno)
70 : else
71 : active_step = .false.
72 : endif
73 :
74 0 : if (active_step) then
75 :
76 0 : call unit_driver_run(curr_indata, phys_state, pbuf2d, cam_out, cam_in, recno)
77 :
78 0 : recno = recno+1
79 :
80 0 : if ( recno > curr_indata%ntimes ) then
81 0 : call drv_input_data_close(curr_indata)
82 0 : current_file = next_file
83 0 : if ( current_file/='NOT_FOUND' ) then
84 0 : call drv_input_data_open( current_file, curr_indata )
85 0 : recno = 1
86 0 : next_file = incr_filename( current_file, filenames_list=offline_driver_fileslist, abort=.false.)
87 : endif
88 : endif
89 :
90 : endif
91 :
92 0 : end subroutine offline_driver_run
93 :
94 : !================================================================================
95 : !================================================================================
96 1536 : subroutine offline_driver_init()
97 0 : use unit_driver, only: unit_driver_init
98 : use drv_input_data, only: drv_input_data_freq
99 : use shr_const_mod, only: SHR_CONST_CDAY
100 : use infnan, only: nan, assignment(=)
101 :
102 1536 : type(drv_input_data_t) :: next_indata
103 :
104 1536 : if (.not.offline_driver_dorun) return
105 :
106 0 : call drv_input_data_open( current_file, curr_indata )
107 :
108 0 : drv_input_data_freq = nan
109 :
110 0 : if (curr_indata%ntimes>1) then
111 0 : drv_input_data_freq = (curr_indata%times(2) - curr_indata%times(1))*SHR_CONST_CDAY ! seconds
112 : else
113 0 : if ( next_file/='NOT_FOUND' ) then
114 0 : call drv_input_data_open( next_file, next_indata )
115 0 : drv_input_data_freq = (next_indata%times(1) - curr_indata%times(1))*SHR_CONST_CDAY ! seconds
116 0 : call drv_input_data_close(next_indata)
117 : endif
118 : endif
119 :
120 0 : call unit_driver_init()
121 :
122 1536 : endsubroutine offline_driver_init
123 :
124 : !=================================================================================
125 : !=================================================================================
126 1536 : subroutine offline_driver_readnl( nlfile )
127 :
128 1536 : use namelist_utils, only: find_group_name
129 : use units, only: getunit, freeunit
130 : use cam_abortutils, only: endrun
131 : use mpishorthand
132 :
133 : ! arguments
134 : character(len=*), intent(in) :: nlfile ! filepath for file containing namelist input
135 :
136 : ! local vars
137 : integer :: unitn, ierr
138 :
139 : character(len=cl) :: offline_driver_infile = ' '
140 :
141 : namelist /offline_driver_nl/ offline_driver_infile, offline_driver_fileslist
142 :
143 1536 : if (masterproc) then
144 :
145 2 : unitn = getunit()
146 2 : open( unitn, file=trim(nlfile), status='old' )
147 2 : call find_group_name(unitn, 'offline_driver_nl', status=ierr)
148 2 : if (ierr == 0) then
149 0 : read(unitn, offline_driver_nl, iostat=ierr)
150 0 : if (ierr /= 0) then
151 0 : call endrun('offline_driver_readnl: ERROR reading namelist')
152 : end if
153 : end if
154 2 : close(unitn)
155 2 : call freeunit(unitn)
156 :
157 : end if
158 :
159 : #ifdef SPMD
160 1536 : call mpibcast (offline_driver_infile, len(offline_driver_infile), mpichar, 0, mpicom)
161 1536 : call mpibcast (offline_driver_fileslist, len(offline_driver_fileslist), mpichar, 0, mpicom)
162 : #endif
163 :
164 1536 : current_file = 'NOT_FOUND'
165 1536 : next_file = 'NOT_FOUND'
166 1536 : offline_driver_dorun = .false.
167 :
168 1536 : if ( len_trim(offline_driver_infile) > 0 ) then
169 0 : current_file = trim(offline_driver_infile)
170 1536 : elseif ( len_trim(offline_driver_fileslist) > 0 ) then
171 0 : current_file = incr_filename( offline_driver_infile, filenames_list=offline_driver_fileslist )
172 : else
173 1536 : offline_driver_dorun = .false.
174 1536 : return
175 : endif
176 :
177 0 : if ( trim(current_file)/='NOT_FOUND' .and. len_trim(current_file) > 0 ) then
178 0 : offline_driver_dorun = .true.
179 0 : if ( len_trim(offline_driver_fileslist) > 0 ) then
180 0 : next_file = incr_filename( current_file, filenames_list=offline_driver_fileslist, abort=.false.)
181 : endif
182 : endif
183 :
184 : endsubroutine offline_driver_readnl
185 :
186 : end module offline_driver
|