Line data Source code
1 : module cam_comp
2 : !-----------------------------------------------------------------------
3 : !
4 : ! Community Atmosphere Model (CAM) component interfaces.
5 : !
6 : ! This interface layer is CAM specific, i.e., it deals entirely with CAM
7 : ! specific data structures. It is the layer above this, either atm_comp_mct
8 : ! or atm_comp_nuopc, which translates between CAM and either MCT or NUOPC
9 : ! data structures in order to interface with the driver/coupler.
10 : !
11 : !-----------------------------------------------------------------------
12 :
13 : use shr_kind_mod, only: r8 => SHR_KIND_R8, cl=>SHR_KIND_CL, cs=>SHR_KIND_CS
14 : use shr_sys_mod, only: shr_sys_flush
15 :
16 : use spmd_utils, only: masterproc, mpicom
17 : use cam_control_mod, only: cam_ctrl_init, cam_ctrl_set_orbit
18 : use runtime_opts, only: read_namelist
19 : use time_manager, only: timemgr_init, get_nstep
20 : use camsrfexch, only: cam_out_t, cam_in_t
21 : use ppgrid, only: begchunk, endchunk
22 : use physics_types, only: physics_state, physics_tend
23 : use dyn_comp, only: dyn_import_t, dyn_export_t
24 :
25 : use physics_buffer, only: physics_buffer_desc
26 : use offline_driver, only: offline_driver_init, offline_driver_dorun, offline_driver_run
27 :
28 : use perf_mod
29 : use cam_logfile, only: iulog
30 : use cam_abortutils, only: endrun
31 :
32 : implicit none
33 : private
34 :
35 : public cam_init ! First phase of CAM initialization
36 : public cam_run1 ! CAM run method phase 1
37 : public cam_run2 ! CAM run method phase 2
38 : public cam_run3 ! CAM run method phase 3
39 : public cam_run4 ! CAM run method phase 4
40 : public cam_final ! CAM Finalization
41 :
42 : type(dyn_import_t) :: dyn_in ! Dynamics import container
43 : type(dyn_export_t) :: dyn_out ! Dynamics export container
44 :
45 : type(physics_state), pointer :: phys_state(:) => null()
46 : type(physics_tend ), pointer :: phys_tend(:) => null()
47 : type(physics_buffer_desc), pointer :: pbuf2d(:,:) => null()
48 :
49 : real(r8) :: dtime_phys ! Time step for physics tendencies. Set by call to
50 : ! stepon_run1, then passed to the phys_run*
51 :
52 : !-----------------------------------------------------------------------
53 : contains
54 : !-----------------------------------------------------------------------
55 :
56 3072 : subroutine cam_init( &
57 1536 : caseid, ctitle, model_doi_url, &
58 : initial_run_in, restart_run_in, branch_run_in, post_assim_in, &
59 1536 : calendar, brnch_retain_casename, aqua_planet, &
60 : single_column, scmlat, scmlon, &
61 : eccen, obliqr, lambm0, mvelpp, &
62 : perpetual_run, perpetual_ymd, &
63 : dtime, start_ymd, start_tod, ref_ymd, ref_tod, &
64 : stop_ymd, stop_tod, curr_ymd, curr_tod, &
65 : cam_out, cam_in)
66 :
67 : !-----------------------------------------------------------------------
68 : !
69 : ! CAM component initialization.
70 : !
71 : !-----------------------------------------------------------------------
72 :
73 : use cam_initfiles, only: cam_initfiles_open
74 : use dyn_grid, only: dyn_grid_init
75 : use phys_grid, only: phys_grid_init
76 : use physpkg, only: phys_register, phys_init
77 : use chem_surfvals, only: chem_surfvals_init
78 : use dyn_comp, only: dyn_init
79 : use cam_restart, only: cam_read_restart
80 : use stepon, only: stepon_init
81 : use ionosphere_interface, only: ionosphere_init
82 : use camsrfexch, only: hub2atm_alloc, atm2hub_alloc
83 : use cam_history, only: intht, write_camiop
84 : use history_scam, only: scm_intht, initialize_iop_history
85 : use cam_pio_utils, only: init_pio_subsystem
86 : use cam_instance, only: inst_suffix
87 : use cam_snapshot_common, only: cam_snapshot_deactivate
88 : use air_composition, only: air_composition_init
89 : use phys_grid_ctem, only: phys_grid_ctem_reg
90 :
91 : ! Arguments
92 : character(len=cl), intent(in) :: caseid ! case ID
93 : character(len=cl), intent(in) :: ctitle ! case title
94 : character(len=cl), intent(in) :: model_doi_url ! CESM model DOI
95 : logical, intent(in) :: initial_run_in ! true => inital run
96 : logical, intent(in) :: restart_run_in ! true => restart run
97 : logical, intent(in) :: branch_run_in ! true => branch run
98 : logical, intent(in) :: post_assim_in ! true => resume mode
99 : character(len=cs), intent(in) :: calendar ! Calendar type
100 : logical, intent(in) :: brnch_retain_casename ! Flag to allow a branch to use the same
101 : ! caseid as the run being branched from.
102 : logical, intent(in) :: aqua_planet ! Flag to run model in "aqua planet" mode
103 :
104 : logical, intent(in) :: single_column
105 : real(r8), intent(in) :: scmlat
106 : real(r8), intent(in) :: scmlon
107 :
108 : real(r8), intent(in) :: eccen
109 : real(r8), intent(in) :: obliqr
110 : real(r8), intent(in) :: lambm0
111 : real(r8), intent(in) :: mvelpp
112 :
113 : logical, intent(in) :: perpetual_run ! true => perpetual mode enabled
114 : integer, intent(in) :: perpetual_ymd ! Perpetual date (YYYYMMDD)
115 : integer, intent(in) :: dtime ! model timestep (sec)
116 :
117 : integer, intent(in) :: start_ymd ! Start date (YYYYMMDD)
118 : integer, intent(in) :: start_tod ! Start time of day (sec)
119 : integer, intent(in) :: curr_ymd ! Start date (YYYYMMDD)
120 : integer, intent(in) :: curr_tod ! Start time of day (sec)
121 : integer, intent(in) :: stop_ymd ! Stop date (YYYYMMDD)
122 : integer, intent(in) :: stop_tod ! Stop time of day (sec)
123 : integer, intent(in) :: ref_ymd ! Reference date (YYYYMMDD)
124 : integer, intent(in) :: ref_tod ! Reference time of day (sec)
125 :
126 : type(cam_out_t), pointer :: cam_out(:) ! Output from CAM to surface
127 : type(cam_in_t) , pointer :: cam_in(:) ! Merged input state to CAM
128 :
129 : ! Local variables
130 : character(len=cs) :: filein ! Input namelist filename
131 : !-----------------------------------------------------------------------
132 :
133 1536 : call init_pio_subsystem()
134 :
135 : ! Initializations using data passed from coupler.
136 : call cam_ctrl_init( &
137 : caseid_in=caseid, &
138 : ctitle_in=ctitle, &
139 : initial_run_in=initial_run_in, &
140 : restart_run_in=restart_run_in, &
141 : branch_run_in=branch_run_in, &
142 : post_assim_in=post_assim_in, &
143 : aqua_planet_in=aqua_planet, &
144 1536 : brnch_retain_casename_in=brnch_retain_casename)
145 :
146 1536 : call cam_ctrl_set_orbit(eccen, obliqr, lambm0, mvelpp)
147 :
148 : call timemgr_init( &
149 : dtime, calendar, start_ymd, start_tod, ref_ymd, &
150 : ref_tod, stop_ymd, stop_tod, curr_ymd, curr_tod, &
151 1536 : perpetual_run, perpetual_ymd, initial_run_in)
152 :
153 : ! Read CAM namelists.
154 1536 : filein = "atm_in" // trim(inst_suffix)
155 1536 : call read_namelist(filein, single_column, scmlat, scmlon)
156 :
157 : ! Open initial or restart file, and topo file if specified.
158 1536 : call cam_initfiles_open()
159 :
160 : ! Initialize grids and dynamics grid decomposition
161 1536 : call dyn_grid_init()
162 :
163 : ! Initialize physics grid decomposition
164 1536 : call phys_grid_init()
165 :
166 : ! Register zonal average grid for phys TEM diagnostics
167 1536 : call phys_grid_ctem_reg()
168 :
169 : ! Register advected tracers and physics buffer fields
170 1536 : call phys_register ()
171 :
172 : ! Initialize ghg surface values before default initial distributions
173 : ! are set in dyn_init
174 1536 : call chem_surfvals_init()
175 :
176 1536 : call air_composition_init()
177 : ! initialize ionosphere
178 1536 : call ionosphere_init()
179 :
180 1536 : if (initial_run_in) then
181 :
182 768 : call dyn_init(dyn_in, dyn_out)
183 :
184 : ! Allocate and setup surface exchange data
185 768 : call atm2hub_alloc(cam_out)
186 768 : call hub2atm_alloc(cam_in)
187 :
188 : else
189 :
190 768 : call cam_read_restart(cam_in, cam_out, dyn_in, dyn_out, pbuf2d, stop_ymd, stop_tod)
191 :
192 : end if
193 :
194 1536 : if (write_camiop) call initialize_iop_history()
195 :
196 1536 : call phys_init( phys_state, phys_tend, pbuf2d, cam_in, cam_out )
197 :
198 1536 : call stepon_init(dyn_in, dyn_out)
199 :
200 1536 : call offline_driver_init()
201 :
202 1536 : if (single_column) call scm_intht()
203 1536 : call intht(model_doi_url)
204 :
205 1536 : call cam_snapshot_deactivate()
206 :
207 1536 : end subroutine cam_init
208 :
209 : !
210 : !-----------------------------------------------------------------------
211 : !
212 741888 : subroutine cam_run1(cam_in, cam_out)
213 : !-----------------------------------------------------------------------
214 : !
215 : ! Purpose: First phase of atmosphere model run method.
216 : ! Runs first phase of dynamics and first phase of
217 : ! physics (before surface model updates).
218 : !
219 : !-----------------------------------------------------------------------
220 :
221 1536 : use physpkg, only: phys_run1
222 : use stepon, only: stepon_run1
223 : use ionosphere_interface,only: ionosphere_run1
224 :
225 : type(cam_in_t) :: cam_in(begchunk:endchunk)
226 : type(cam_out_t) :: cam_out(begchunk:endchunk)
227 :
228 : !-----------------------------------------------------------------------
229 :
230 370944 : if (offline_driver_dorun) return
231 :
232 : !----------------------------------------------------------
233 : ! First phase of dynamics (at least couple from dynamics to physics)
234 : ! Return time-step for physics from dynamics.
235 : !----------------------------------------------------------
236 370944 : call t_barrierf ('sync_stepon_run1', mpicom)
237 370944 : call t_startf ('stepon_run1')
238 370944 : call stepon_run1( dtime_phys, phys_state, phys_tend, pbuf2d, dyn_in, dyn_out )
239 370944 : call t_stopf ('stepon_run1')
240 :
241 : !----------------------------------------------------------
242 : ! first phase of ionosphere -- write to IC file if needed
243 : !----------------------------------------------------------
244 370944 : call ionosphere_run1(pbuf2d)
245 :
246 : !
247 : !----------------------------------------------------------
248 : ! PHYS_RUN Call the Physics package
249 : !----------------------------------------------------------
250 : !
251 370944 : call t_barrierf ('sync_phys_run1', mpicom)
252 370944 : call t_startf ('phys_run1')
253 370944 : call phys_run1(phys_state, dtime_phys, phys_tend, pbuf2d, cam_in, cam_out)
254 370944 : call t_stopf ('phys_run1')
255 :
256 370944 : end subroutine cam_run1
257 :
258 : !
259 : !-----------------------------------------------------------------------
260 : !
261 :
262 738816 : subroutine cam_run2( cam_out, cam_in )
263 : !-----------------------------------------------------------------------
264 : !
265 : ! Purpose: Second phase of atmosphere model run method.
266 : ! Run the second phase physics, run methods that
267 : ! require the surface model updates. And run the
268 : ! second phase of dynamics that at least couples
269 : ! between physics to dynamics.
270 : !
271 : !-----------------------------------------------------------------------
272 :
273 370944 : use physpkg, only: phys_run2
274 : use stepon, only: stepon_run2
275 : use ionosphere_interface, only: ionosphere_run2
276 :
277 : type(cam_out_t), intent(inout) :: cam_out(begchunk:endchunk)
278 : type(cam_in_t), intent(inout) :: cam_in(begchunk:endchunk)
279 :
280 369408 : if (offline_driver_dorun) then
281 0 : call offline_driver_run( phys_state, pbuf2d, cam_out, cam_in )
282 : return
283 : endif
284 :
285 : !
286 : ! Second phase of physics (after surface model update)
287 : !
288 369408 : call t_barrierf ('sync_phys_run2', mpicom)
289 369408 : call t_startf ('phys_run2')
290 369408 : call phys_run2(phys_state, dtime_phys, phys_tend, pbuf2d, cam_out, cam_in )
291 369408 : call t_stopf ('phys_run2')
292 :
293 : !
294 : ! Second phase of dynamics (at least couple from physics to dynamics)
295 : !
296 369408 : call t_barrierf ('sync_stepon_run2', mpicom)
297 369408 : call t_startf ('stepon_run2')
298 369408 : call stepon_run2( phys_state, phys_tend, dyn_in, dyn_out )
299 369408 : call t_stopf ('stepon_run2')
300 :
301 : !
302 : ! Ion transport
303 : !
304 369408 : call t_startf('ionosphere_run2')
305 369408 : call ionosphere_run2( phys_state, pbuf2d )
306 369408 : call t_stopf ('ionosphere_run2')
307 :
308 369408 : end subroutine cam_run2
309 :
310 : !
311 : !-----------------------------------------------------------------------
312 : !
313 :
314 738816 : subroutine cam_run3( cam_out )
315 : !-----------------------------------------------------------------------
316 : !
317 : ! Purpose: Third phase of atmosphere model run method. This consists
318 : ! of the third phase of the dynamics. For some dycores
319 : ! this will be the actual dynamics run, for others the
320 : ! dynamics happens before physics in phase 1.
321 : !
322 : !-----------------------------------------------------------------------
323 369408 : use stepon, only: stepon_run3
324 :
325 : type(cam_out_t), intent(inout) :: cam_out(begchunk:endchunk)
326 : !-----------------------------------------------------------------------
327 :
328 369408 : if (offline_driver_dorun) return
329 :
330 : !
331 : ! Third phase of dynamics
332 : !
333 369408 : call t_barrierf ('sync_stepon_run3', mpicom)
334 369408 : call t_startf ('stepon_run3')
335 369408 : call stepon_run3( dtime_phys, cam_out, phys_state, dyn_in, dyn_out )
336 :
337 369408 : call t_stopf ('stepon_run3')
338 :
339 369408 : end subroutine cam_run3
340 :
341 : !
342 : !-----------------------------------------------------------------------
343 : !
344 :
345 738816 : subroutine cam_run4( cam_out, cam_in, rstwr, nlend, &
346 : yr_spec, mon_spec, day_spec, sec_spec )
347 :
348 : !-----------------------------------------------------------------------
349 : !
350 : ! Purpose: Final phase of atmosphere model run method. This consists
351 : ! of all the restart output, history writes, and other
352 : ! file output.
353 : !
354 : !-----------------------------------------------------------------------
355 369408 : use dycore_budget, only: print_budget
356 : use cam_history, only: wshist, wrapup, hstwr
357 : use cam_restart, only: cam_write_restart
358 : use qneg_module, only: qneg_print_summary
359 : use time_manager, only: is_last_step
360 :
361 : type(cam_out_t), intent(inout) :: cam_out(begchunk:endchunk)
362 : type(cam_in_t) , intent(inout) :: cam_in(begchunk:endchunk)
363 : logical , intent(in) :: rstwr ! true => write restart file
364 : logical , intent(in) :: nlend ! true => this is final timestep
365 : integer , intent(in), optional :: yr_spec ! Simulation year
366 : integer , intent(in), optional :: mon_spec ! Simulation month
367 : integer , intent(in), optional :: day_spec ! Simulation day
368 : integer , intent(in), optional :: sec_spec ! Seconds into current simulation day
369 :
370 : !----------------------------------------------------------
371 : ! History and restart logic: Write and/or dispose history tapes if required
372 : !----------------------------------------------------------
373 : !
374 369408 : call t_barrierf ('sync_wshist', mpicom)
375 369408 : call t_startf ('wshist')
376 369408 : call wshist ()
377 369408 : call t_stopf ('wshist')
378 :
379 : !
380 : ! Write restart files
381 : !
382 369408 : if (rstwr) then
383 1536 : call t_startf ('cam_write_restart')
384 1536 : if (present(yr_spec).and.present(mon_spec).and.present(day_spec).and.present(sec_spec)) then
385 : call cam_write_restart(cam_in, cam_out, dyn_out, pbuf2d, &
386 1536 : yr_spec=yr_spec, mon_spec=mon_spec, day_spec=day_spec, sec_spec= sec_spec )
387 : else
388 0 : call cam_write_restart(cam_in, cam_out, dyn_out, pbuf2d )
389 : end if
390 1536 : call t_stopf ('cam_write_restart')
391 : end if
392 :
393 369408 : call t_startf ('cam_run4_wrapup')
394 369408 : call wrapup(rstwr, nlend)
395 369408 : call t_stopf ('cam_run4_wrapup')
396 :
397 369408 : call qneg_print_summary(is_last_step())
398 :
399 369408 : call print_budget(hstwr)
400 :
401 369408 : call shr_sys_flush(iulog)
402 :
403 369408 : end subroutine cam_run4
404 :
405 : !
406 : !-----------------------------------------------------------------------
407 : !
408 :
409 1536 : subroutine cam_final( cam_out, cam_in )
410 : !-----------------------------------------------------------------------
411 : !
412 : ! Purpose: CAM finalization.
413 : !
414 : !-----------------------------------------------------------------------
415 369408 : use stepon, only: stepon_final
416 : use physpkg, only: phys_final
417 : use cam_initfiles, only: cam_initfiles_close
418 : use camsrfexch, only: atm2hub_deallocate, hub2atm_deallocate
419 : use ionosphere_interface, only: ionosphere_final
420 : use cam_control_mod, only: initial_run
421 :
422 : !
423 : ! Arguments
424 : !
425 : type(cam_out_t), pointer :: cam_out(:) ! Output from CAM to surface
426 : type(cam_in_t), pointer :: cam_in(:) ! Input from merged surface to CAM
427 :
428 : ! Local variables
429 : integer :: nstep ! Current timestep number.
430 : !-----------------------------------------------------------------------
431 :
432 1536 : call phys_final( phys_state, phys_tend , pbuf2d)
433 1536 : call stepon_final(dyn_in, dyn_out)
434 1536 : call ionosphere_final()
435 :
436 1536 : if (initial_run) then
437 768 : call cam_initfiles_close()
438 : end if
439 :
440 1536 : call hub2atm_deallocate(cam_in)
441 1536 : call atm2hub_deallocate(cam_out)
442 :
443 : ! This flush attempts to ensure that asynchronous diagnostic prints from all
444 : ! processes do not get mixed up with the "END OF MODEL RUN" message printed
445 : ! by masterproc below. The test-model script searches for this message in the
446 : ! output log to figure out if CAM completed successfully.
447 1536 : call shr_sys_flush( 0 ) ! Flush all output to standard error
448 1536 : call shr_sys_flush( iulog ) ! Flush all output to the CAM log file
449 :
450 1536 : if (masterproc) then
451 2 : nstep = get_nstep()
452 2 : write(iulog,9300) nstep-1,nstep
453 : 9300 format (//'Number of completed timesteps:',i6,/,'Time step ',i6, &
454 : ' partially done to provide convectively adjusted and ', &
455 : 'time filtered values for history tape.')
456 2 : write(iulog,*)' '
457 2 : write(iulog,*)'******* END OF MODEL RUN *******'
458 : end if
459 :
460 1536 : end subroutine cam_final
461 :
462 : !-----------------------------------------------------------------------
463 :
464 : end module cam_comp
|