CAM Component  1.2.2
 All Classes Files Functions Variables
atm_comp_mct.F90
Go to the documentation of this file.
2 
3  use pio , only: file_desc_t, io_desc_t, var_desc_t, pio_double, pio_def_dim, &
4  pio_put_att, pio_enddef, pio_initdecomp, pio_read_darray, pio_freedecomp, &
5  pio_closefile, pio_write_darray, pio_def_var, pio_inq_varid, &
6  pio_noerr, pio_bcast_error, pio_internal_error, pio_seterrorhandling
7  use mct_mod
8  use esmf
9  use seq_flds_mod
10  use seq_cdata_mod
11  use seq_infodata_mod
12  use seq_timemgr_mod
13 
14  use shr_kind_mod , only: r8 => shr_kind_r8, cl=>shr_kind_cl
15  use shr_file_mod , only: shr_file_getunit, shr_file_freeunit, &
16  shr_file_setlogunit, shr_file_setloglevel, &
17  shr_file_getlogunit, shr_file_getloglevel, &
18  shr_file_setio
19  use shr_sys_mod , only: shr_sys_flush, shr_sys_abort
20 
21  use cam_cpl_indices
22  use cam_comp
23  use cam_instance , only: cam_instance_init, inst_suffix
24  use cam_control_mod , only: nsrest, adiabatic, ideal_phys, aqua_planet, eccen, obliqr, lambm0, mvelpp
25  use radiation , only: radiation_get, radiation_do, radiation_nextsw_cday
26  use phys_grid , only: get_ncols_p, get_gcol_all_p, &
27  ngcols, get_gcol_p, get_rlat_all_p, &
28  get_rlon_all_p, get_area_all_p
29  use ppgrid , only: pcols, begchunk, endchunk
30  use dyn_grid , only: get_horiz_grid_dim_d
31  use camsrfexch , only: cam_out_t, cam_in_t
32  use cam_restart , only: get_restcase, get_restartdir
33  use cam_history , only: outfld, ctitle
34  use abortutils , only: endrun
35  use filenames , only: interpret_filename_spec, caseid, brnch_retain_casename
36 #ifdef SPMD
37  use spmd_utils , only: spmdinit, masterproc, iam
38  use mpishorthand , only: mpicom
39 #else
40  use spmd_utils , only: spmdinit, masterproc, mpicom, iam
41 #endif
42  use time_manager , only: get_curr_calday, advance_timestep, get_curr_date, get_nstep, &
43  is_first_step, get_step_size, timemgr_init, timemgr_check_restart
44  use iofilemod
45  use perf_mod
46  use cam_logfile , only: iulog
47  use co2_cycle , only: c_i, co2_readflux_ocn, co2_readflux_fuel, co2_transport, &
48  co2_time_interp_ocn, co2_time_interp_fuel, data_flux_ocn, data_flux_fuel
49  use physconst , only: mwco2
50  use runtime_opts , only: read_namelist
51  use phys_control , only: cam_chempkg_is
52  use scammod , only: single_column,scmlat,scmlon
53 
54 !
55 ! !PUBLIC TYPES:
56  implicit none
57  save
58  private ! except
59 
60 !--------------------------------------------------------------------------
61 ! Public interfaces
62 !--------------------------------------------------------------------------
63 
64  public :: atm_init_mct
65  public :: atm_run_mct
66  public :: atm_final_mct
67 
68 !--------------------------------------------------------------------------
69 ! Private interfaces
70 !--------------------------------------------------------------------------
71 
72  private :: atm_setgsmap_mct
73  private :: atm_import_mct
74  private :: atm_export_mct
75  private :: atm_domain_mct
76  private :: atm_read_srfrest_mct
77  private :: atm_write_srfrest_mct
78 
79 !--------------------------------------------------------------------------
80 ! Private data
81 !--------------------------------------------------------------------------
82 
83  type(cam_in_t) , pointer :: cam_in(:)
84  type(cam_out_t), pointer :: cam_out(:)
85 
86  type(mct_avect) :: a2x_a_snap
87  type(mct_avect) :: a2x_a_sum
88 
89  integer, parameter :: nlen = 256 ! Length of character strings
90  character(len=nlen) :: fname_srf_cam ! surface restart filename
91  character(len=nlen) :: pname_srf_cam ! surface restart full pathname
92 
93  ! Filename specifier for restart surface file
94  character(len=cl) :: rsfilename_spec_cam
95 !
96 ! Time averaged counter for flux fields
97 !
98  integer :: avg_count
99 !
100 ! Time averaged flux fields
101 !
102  character(*), parameter :: a2x_avg_flds = "Faxa_rainc:Faxa_rainl:Faxa_snowc:Faxa_snowl"
103 !
104 ! Are all surface types present
105 !
106  logical :: lnd_present ! if true => land is present
107  logical :: ocn_present ! if true => ocean is present
108 
109 !
110 !================================================================================
111 CONTAINS
112 !================================================================================
113 
114  subroutine atm_init_mct( EClock, cdata_a, x2a_a, a2x_a, NLFilename )
115 
116  !-----------------------------------------------------------------------
117  !
118  ! Arguments
119  !
120  type(esmf_clock),intent(in) :: eclock
121  type(seq_cdata), intent(inout) :: cdata_a
122  type(mct_avect), intent(inout) :: x2a_a
123  type(mct_avect), intent(inout) :: a2x_a
124  character(len=*), optional, intent(IN) :: nlfilename ! Namelist filename
125  !
126  ! Locals
127  !
128  type(mct_gsmap), pointer :: gsmap_atm
129  type(mct_ggrid), pointer :: dom_a
130  type(seq_infodata_type),pointer :: infodata
131  integer :: atmid
132  integer :: mpicom_atm
133  integer :: lsize
134  integer :: iradsw
135  logical :: exists ! true if file exists
136  real(r8):: nextsw_cday ! calendar of next atm shortwave
137  integer :: stepno ! time step
138  integer :: dtime_sync ! integer timestep size
139  integer :: currentymd ! current year-month-day
140  integer :: dtime ! time step increment (sec)
141  integer :: atm_cpl_dt ! driver atm coupling time step
142  integer :: nstep ! CAM nstep
143  real(r8):: caldayp1 ! CAM calendar day for for next cam time step
144  integer :: dtime_cam ! Time-step increment (sec)
145  integer :: ymd ! CAM current date (YYYYMMDD)
146  integer :: yr ! CAM current year
147  integer :: mon ! CAM current month
148  integer :: day ! CAM current day
149  integer :: tod ! CAM current time of day (sec)
150  integer :: start_ymd ! Start date (YYYYMMDD)
151  integer :: start_tod ! Start time of day (sec)
152  integer :: ref_ymd ! Reference date (YYYYMMDD)
153  integer :: ref_tod ! Reference time of day (sec)
154  integer :: stop_ymd ! Stop date (YYYYMMDD)
155  integer :: stop_tod ! Stop time of day (sec)
156  logical :: perpetual_run ! If in perpetual mode or not
157  integer :: perpetual_ymd ! Perpetual date (YYYYMMDD)
158  integer :: shrlogunit,shrloglev ! old values
159  logical :: first_time = .true.
160  character(len=SHR_KIND_CS) :: calendar ! Calendar type
161  character(len=SHR_KIND_CS) :: starttype ! infodata start type
162  integer :: lbnum
163  integer :: hdim1_d, hdim2_d ! dimensions of rectangular horizontal grid
164  ! data structure, If 1D data structure, then
165  ! hdim2_d == 1.
166  character(len=64) :: filein ! Input namelist filename
167  !-----------------------------------------------------------------------
168  !
169  ! Determine cdata points
170  !
171 #if (defined _MEMTRACE)
172  if(masterproc) then
173  lbnum=1
174  call memmon_dump_fort('memmon.out','atm_init_mct:start::',lbnum)
175  endif
176 #endif
177  call seq_cdata_setptrs(cdata_a, id=atmid, mpicom=mpicom_atm, &
178  gsmap=gsmap_atm, dom=dom_a, infodata=infodata)
179 
180  if (first_time) then
181 
182  call cam_instance_init(atmid)
183 
184  ! Set filename specifier for restart surface file
185  ! (%c=caseid, $y=year, $m=month, $d=day, $s=seconds in day)
186  rsfilename_spec_cam = '%c.cam' // trim(inst_suffix) // '.rs.%y-%m-%d-%s.nc'
187 
188  ! Determine attribute vector indices
189 
190  call cam_cpl_indices_set()
191 
192  ! Redirect share output to cam log
193 
194  call spmdinit(mpicom_atm)
195 
196  if (masterproc) then
197  inquire(file='atm_modelio.nml'//trim(inst_suffix), exist=exists)
198  if (exists) then
199  iulog = shr_file_getunit()
200  call shr_file_setio('atm_modelio.nml'//trim(inst_suffix), iulog)
201  endif
202  write(iulog,*) "CAM atmosphere model initialization"
203  endif
204 
205  call shr_file_getlogunit(shrlogunit)
206  call shr_file_getloglevel(shrloglev)
207  call shr_file_setlogunit(iulog)
208  !
209  ! Consistency check
210  !
211  if (co2_readflux_ocn .and. index_x2a_faoo_fco2_ocn /= 0) then
212  write(iulog,*)'error co2_readFlux_ocn and index_x2a_Faoo_fco2_ocn cannot both be active'
213  call shr_sys_abort()
214  end if
215  !
216  ! Get data from infodata object
217  !
218  call seq_infodata_getdata( infodata, &
219  case_name=caseid, case_desc=ctitle, &
220  start_type=starttype, &
221  atm_adiabatic=adiabatic, &
222  atm_ideal_phys=ideal_phys, &
223  aqua_planet=aqua_planet, &
224  brnch_retain_casename=brnch_retain_casename, &
225  single_column=single_column, scmlat=scmlat, scmlon=scmlon, &
226  orb_eccen=eccen, orb_mvelpp=mvelpp, orb_lambm0=lambm0, orb_obliqr=obliqr, &
227  lnd_present=lnd_present, ocn_present=ocn_present, &
228  perpetual=perpetual_run, perpetual_ymd=perpetual_ymd)
229  !
230  ! Get nsrest from startup type methods
231  !
232  if ( trim(starttype) == trim(seq_infodata_start_type_start)) then
233  nsrest = 0
234  else if (trim(starttype) == trim(seq_infodata_start_type_cont) ) then
235  nsrest = 1
236  else if (trim(starttype) == trim(seq_infodata_start_type_brnch)) then
237  nsrest = 3
238  else
239  write(iulog,*) 'atm_comp_mct: ERROR: unknown starttype'
240  call shr_sys_abort()
241  end if
242  !
243  ! Initialize time manager.
244  !
245  call seq_timemgr_eclockgetdata(eclock, &
246  start_ymd=start_ymd, start_tod=start_tod, &
247  ref_ymd=ref_ymd, ref_tod=ref_tod, &
248  stop_ymd=stop_ymd, stop_tod=stop_tod, &
249  calendar=calendar )
250  !
251  ! Read namelist
252  !
253  filein = "atm_in" // trim(inst_suffix)
254  call read_namelist(single_column_in=single_column, scmlat_in=scmlat, &
255  scmlon_in=scmlon, nlfilename_in=filein)
256  !
257  ! Initialize cam time manager
258  !
259  if ( nsrest == 0 )then
260  call timemgr_init( calendar_in=calendar, start_ymd=start_ymd, &
261  start_tod=start_tod, ref_ymd=ref_ymd, &
262  ref_tod=ref_tod, stop_ymd=stop_ymd, &
263  stop_tod=stop_tod, &
264  perpetual_run=perpetual_run, &
265  perpetual_ymd=perpetual_ymd )
266  end if
267  !
268  ! First phase of cam initialization
269  ! Initialize mpicom_atm, allocate cam_in and cam_out and determine
270  ! atm decomposition (needed to initialize gsmap)
271  ! for an initial run, cam_in and cam_out are allocated in cam_initial
272  ! for a restart/branch run, cam_in and cam_out are allocated in restart
273  ! Set defaults then override with user-specified input and initialize time manager
274  ! Note that the following arguments are needed to cam_init for timemgr_restart only
275  !
276  call cam_init( cam_out, cam_in, mpicom_atm, &
277  start_ymd, start_tod, ref_ymd, ref_tod, stop_ymd, stop_tod, &
278  perpetual_run, perpetual_ymd, calendar)
279  !
280  ! Check consistency of restart time information with input clock
281  !
282  if (nsrest /= 0) then
283  dtime_cam = get_step_size()
284  call timemgr_check_restart( calendar, start_ymd, start_tod, ref_ymd, &
285  ref_tod, dtime_cam, perpetual_run, perpetual_ymd)
286  end if
287  !
288  ! Initialize MCT gsMap, domain and attribute vectors
289  !
290  call atm_setgsmap_mct( mpicom_atm, atmid, gsmap_atm )
291  lsize = mct_gsmap_lsize(gsmap_atm, mpicom_atm)
292  !
293  ! Initialize MCT domain
294  !
295  call atm_domain_mct( lsize, gsmap_atm, dom_a )
296  !
297  ! Initialize MCT attribute vectors
298  !
299  call mct_avect_init(a2x_a, rlist=seq_flds_a2x_fields, lsize=lsize)
300  call mct_avect_zero(a2x_a)
301 
302  call mct_avect_init(x2a_a, rlist=seq_flds_x2a_fields, lsize=lsize)
303  call mct_avect_zero(x2a_a)
304 
305  call mct_avect_init(a2x_a_snap, rlist=a2x_avg_flds, lsize=lsize)
306  call mct_avect_zero(a2x_a_snap)
307 
308  call mct_avect_init(a2x_a_sum , rlist=a2x_avg_flds, lsize=lsize)
309  call mct_avect_zero(a2x_a_sum )
310  !
311  ! Initialize averaging counter
312  !
313  avg_count = 0
314  !
315  ! Create initial atm export state
316  !
317  call atm_export_mct( cam_out, a2x_a )
318  !
319  ! Set flag to specify that an extra albedo calculation is to be done (i.e. specify active)
320  !
321  call seq_infodata_putdata(infodata, atm_prognostic=.true.)
322  call get_horiz_grid_dim_d(hdim1_d, hdim2_d)
323  call seq_infodata_putdata(infodata, atm_nx=hdim1_d, atm_ny=hdim2_d)
324 
325  ! Set flag to indicate that CAM will provide carbon and dust deposition fluxes.
326  ! This is now hardcoded to .true. since the ability of CICE to read these
327  ! fluxes from a file has been removed.
328  call seq_infodata_putdata(infodata, atm_aero=.true.)
329 
330  !
331  ! Set time step of radiation computation as the current calday
332  ! This will only be used on the first timestep of an initial run
333  !
334  if (nsrest == 0) then
335  nextsw_cday = get_curr_calday()
336  call seq_infodata_putdata( infodata, nextsw_cday=nextsw_cday )
337  end if
338 
339  ! End redirection of share output to cam log
340 
341  call shr_file_setlogunit(shrlogunit)
342  call shr_file_setloglevel(shrloglev)
343 
344  first_time = .false.
345 
346  else
347 
348  ! For initial run, run cam radiation/clouds and return
349  ! For restart run, read restart x2a_a
350  ! Note - a2x_a is computed upon the completion of the previous run - cam_run1 is called
351  ! only for the purposes of finishing the flux averaged calculation to compute a2x_a
352  ! Note - cam_run1 is called on restart only to have cam internal state consistent with the
353  ! a2x_a state sent to the coupler
354 
355  ! Redirect share output to cam log
356 
357  call shr_file_getlogunit(shrlogunit)
358  call shr_file_getloglevel(shrloglev)
359  call shr_file_setlogunit(iulog)
360 
361  call seq_timemgr_eclockgetdata(eclock,curr_ymd=currentymd, stepno=stepno, dtime=dtime_sync )
362  if (stepno == 0) then
363  call atm_import_mct( x2a_a, cam_in )
364  call cam_run1( cam_in, cam_out )
365  call atm_export_mct( cam_out, a2x_a )
366  else
367  call atm_read_srfrest_mct( eclock, cdata_a, x2a_a, a2x_a )
368  call atm_import_mct( x2a_a, cam_in )
369  call cam_run1( cam_in, cam_out )
370  end if
371 
372  ! Compute time of next radiation computation, like in run method for exact restart
373 
374 ! tcx was
375 ! nextsw_cday = radiation_nextsw_cday()
376 
377  call seq_timemgr_eclockgetdata(eclock,dtime=atm_cpl_dt)
378  dtime = get_step_size()
379  nstep = get_nstep()
380  if (nstep < 1 .or. dtime < atm_cpl_dt) then
381  nextsw_cday = radiation_nextsw_cday()
382  else if (dtime == atm_cpl_dt) then
383  caldayp1 = get_curr_calday(offset=int(dtime))
384  nextsw_cday = radiation_nextsw_cday()
385  if (caldayp1 /= nextsw_cday) nextsw_cday = -1._r8
386  else
387  call shr_sys_abort('dtime must be less than or equal to atm_cpl_dt')
388  end if
389  call seq_infodata_putdata( infodata, nextsw_cday=nextsw_cday )
390 
391  ! End redirection of share output to cam log
392 
393  call shr_file_setlogunit(shrlogunit)
394  call shr_file_setloglevel(shrloglev)
395 
396  end if
397 
398 #if (defined _MEMTRACE )
399  if(masterproc) then
400  lbnum=1
401  call memmon_dump_fort('memmon.out','atm_init_mct:end::',lbnum)
402  call memmon_reset_addr()
403  endif
404 #endif
405 
406  call shr_sys_flush(iulog)
407 
408  end subroutine atm_init_mct
409 
410 !================================================================================
411 
412  subroutine atm_run_mct( EClock, cdata_a, x2a_a, a2x_a)
413 
414  !-----------------------------------------------------------------------
415  !
416  ! Uses
417  !
418  use time_manager, only: advance_timestep, get_curr_date, get_curr_calday, &
419  get_nstep, get_step_size
420 ! use iop, only: scam_use_iop_srf
421  use pmgrid, only: plev, plevp
422  use constituents, only: pcnst
423  use shr_sys_mod, only: shr_sys_flush
424  use chemistry, only: chem_reset_fluxes
425  use offline_driver, only: offline_driver_dorun, offline_driver_end_of_data
426 
427  !
428  ! Arguments
429  !
430  type(esmf_clock) ,intent(in) :: eclock
431  type(seq_cdata) ,intent(inout) :: cdata_a
432  type(mct_avect) ,intent(inout) :: x2a_a
433  type(mct_avect) ,intent(inout) :: a2x_a
434  !
435  ! Local variables
436  !
437  type(seq_infodata_type),pointer :: infodata
438  integer :: lsize ! size of attribute vector
439  integer :: stepno ! time step
440  integer :: dtime_sync ! integer timestep size
441  integer :: currentymd ! current year-month-day
442  integer :: iradsw ! shortwave radation frequency (time steps)
443  logical :: dosend ! true => send data back to driver
444  integer :: dtime ! time step increment (sec)
445  integer :: atm_cpl_dt ! driver atm coupling time step
446  integer :: ymd_sync ! Sync date (YYYYMMDD)
447  integer :: yr_sync ! Sync current year
448  integer :: mon_sync ! Sync current month
449  integer :: day_sync ! Sync current day
450  integer :: tod_sync ! Sync current time of day (sec)
451  integer :: ymd ! CAM current date (YYYYMMDD)
452  integer :: yr ! CAM current year
453  integer :: mon ! CAM current month
454  integer :: day ! CAM current day
455  integer :: tod ! CAM current time of day (sec)
456  integer :: nstep ! CAM nstep
457  integer :: shrlogunit,shrloglev ! old values
458  real(r8):: caldayp1 ! CAM calendar day for for next cam time step
459  real(r8):: nextsw_cday ! calendar of next atm shortwave
460  logical :: rstwr ! .true. ==> write restart file before returning
461  logical :: nlend ! Flag signaling last time-step
462  logical :: rstwr_sync ! .true. ==> write restart file before returning
463  logical :: nlend_sync ! Flag signaling last time-step
464  logical :: first_time = .true.
465  character(len=*), parameter :: subname="atm_run_mct"
466  !-----------------------------------------------------------------------
467  integer :: lbnum
468 
469 #if (defined _MEMTRACE)
470  if(masterproc) then
471  lbnum=1
472  call memmon_dump_fort('memmon.out',subname //':start::',lbnum)
473  endif
474 #endif
475 
476  ! Redirect share output to cam log
477 
478  call shr_file_getlogunit(shrlogunit)
479  call shr_file_getloglevel(shrloglev)
480  call shr_file_setlogunit(iulog)
481 
482  ! Note that sync clock time should match cam time at end of time step/loop not beginning
483 
484  call seq_cdata_setptrs(cdata_a, infodata=infodata)
485  call seq_timemgr_eclockgetdata(eclock,curr_ymd=ymd_sync,curr_tod=tod_sync, &
486  curr_yr=yr_sync,curr_mon=mon_sync,curr_day=day_sync)
487 
488  !load orbital parameters
489  call seq_infodata_getdata( infodata, &
490  orb_eccen=eccen, orb_mvelpp=mvelpp, orb_lambm0=lambm0, orb_obliqr=obliqr)
491 
492  nlend_sync = seq_timemgr_stopalarmison(eclock)
493  rstwr_sync = seq_timemgr_restartalarmison(eclock)
494 
495  ! Map input from mct to cam data structure
496 
497  call t_startf('CAM_import')
498  call atm_import_mct( x2a_a, cam_in )
499  call t_stopf('CAM_import')
500 
501  ! Cycle over all time steps in the atm coupling interval
502 
503  dosend = .false.
504  do while (.not. dosend)
505 
506  ! (re)set surface fluxes of chem tracers here to MEGAN fluxes (from CLM)
507  ! or to zero so that fluxes read from file can be added to MEGAN
508  call chem_reset_fluxes( x2a_a%rAttr, cam_in )
509 
510  ! Determine if dosend
511  ! When time is not updated at the beginning of the loop - then return only if
512  ! are in sync with clock before time is updated
513 
514  call get_curr_date( yr, mon, day, tod )
515  ymd = yr*10000 + mon*100 + day
516  tod = tod
517  if( offline_driver_dorun ) then
518  dosend = offline_driver_end_of_data()
519  else
520  dosend = (seq_timemgr_eclockdateinsync( eclock, ymd, tod))
521  endif
522 
523  ! Determine if time to write cam restart and stop
524 
525  rstwr = .false.
526  if (rstwr_sync .and. dosend) rstwr = .true.
527  nlend = .false.
528  if (nlend_sync .and. dosend) nlend = .true.
529 
530  ! Single column specific input
531 
532  if (single_column) then
533  call scam_use_iop_srf( cam_in )
534  endif
535 
536  ! Run CAM (run2, run3, run4)
537 
538  call t_startf('CAM_run2')
539  call cam_run2( cam_out, cam_in )
540  call t_stopf('CAM_run2')
541 
542  call t_startf('CAM_run3')
543  call cam_run3( cam_out )
544  call t_stopf('CAM_run3')
545 
546  call t_startf('CAM_run4')
547  call cam_run4( cam_out, cam_in, rstwr, nlend, &
548  yr_spec=yr_sync, mon_spec=mon_sync, day_spec=day_sync, sec_spec=tod_sync)
549  call t_stopf('CAM_run4')
550 
551  ! Advance cam time step
552  if( .not.offline_driver_dorun ) then
553  call t_startf('CAM_adv_timestep')
554  call advance_timestep()
555  call t_stopf('CAM_adv_timestep')
556  endif
557 
558  ! Run cam radiation/clouds (run1)
559 
560  call t_startf('CAM_run1')
561  call cam_run1( cam_in, cam_out )
562  call t_stopf('CAM_run1')
563 
564  ! Map output from cam to mct data structures
565 
566  call t_startf('CAM_export')
567  call atm_export_mct( cam_out, a2x_a )
568  call t_stopf('CAM_export')
569 
570  ! Compute snapshot attribute vector for accumulation
571 
572 ! don't accumulate on first coupling freq ts1 and ts2
573 ! for consistency with ccsm3 when flxave is off
574  nstep = get_nstep()
575  if (nstep <= 2) then
576  call mct_avect_copy( a2x_a, a2x_a_sum )
577  avg_count = 1
578  else
579  call mct_avect_copy( a2x_a, a2x_a_snap )
580  call mct_avect_accum( avin=a2x_a_snap, avout=a2x_a_sum )
581  avg_count = avg_count + 1
582  endif
583 
584  end do
585 
586  ! Finish accumulation of attribute vector and average and copy accumulation
587  ! field into output attribute vector
588 
589  call mct_avect_avg( a2x_a_sum, avg_count)
590  call mct_avect_copy( a2x_a_sum, a2x_a )
591  call mct_avect_zero( a2x_a_sum)
592  avg_count = 0
593 
594  ! Get time of next radiation calculation - albedos will need to be
595  ! calculated by each surface model at this time
596 
597  call seq_timemgr_eclockgetdata(eclock,dtime=atm_cpl_dt)
598  dtime = get_step_size()
599  if (dtime < atm_cpl_dt) then
600  nextsw_cday = radiation_nextsw_cday()
601  else if (dtime == atm_cpl_dt) then
602  caldayp1 = get_curr_calday(offset=int(dtime))
603  nextsw_cday = radiation_nextsw_cday()
604  if (caldayp1 /= nextsw_cday) nextsw_cday = -1._r8
605  else
606  call shr_sys_abort('dtime must be less than or equal to atm_cpl_dt')
607  end if
608  call seq_infodata_putdata( infodata, nextsw_cday=nextsw_cday )
609 
610  ! Write merged surface data restart file if appropriate
611 
612  if (rstwr_sync) then
613  call atm_write_srfrest_mct( cdata_a, x2a_a, a2x_a, &
614  yr_spec=yr_sync, mon_spec=mon_sync, day_spec=day_sync, sec_spec=tod_sync)
615  end if
616 
617  ! Check for consistency of internal cam clock with master sync clock
618 
619  dtime = get_step_size()
620  call get_curr_date( yr, mon, day, tod, offset=-dtime )
621  ymd = yr*10000 + mon*100 + day
622  tod = tod
623  if ((.not.seq_timemgr_eclockdateinsync( eclock, ymd, tod )) .and. (.not.offline_driver_dorun))then
624  call seq_timemgr_eclockgetdata(eclock, curr_ymd=ymd_sync, curr_tod=tod_sync )
625  write(iulog,*)' cam ymd=',ymd ,' cam tod= ',tod
626  write(iulog,*)'sync ymd=',ymd_sync,' sync tod= ',tod_sync
627  call shr_sys_abort( subname//': CAM clock is not in sync with master Sync Clock' )
628  end if
629 
630  ! End redirection of share output to cam log
631 
632  call shr_file_setlogunit(shrlogunit)
633  call shr_file_setloglevel(shrloglev)
634 
635 #if (defined _MEMTRACE)
636  if(masterproc) then
637  lbnum=1
638  call memmon_dump_fort('memmon.out',subname //':end::',lbnum)
639  call memmon_reset_addr()
640  endif
641 #endif
642 
643  end subroutine atm_run_mct
644 
645 !================================================================================
646 
647  subroutine atm_final_mct( EClock, cdata_a, x2a_a, a2x_a)
648  type(esmf_clock) ,intent(in) :: eclock
649  type(seq_cdata) ,intent(inout) :: cdata_a
650  type(mct_avect) ,intent(inout) :: x2a_a
651  type(mct_avect) ,intent(inout) :: a2x_a
652 
653  call cam_final( cam_out, cam_in )
654 
655  end subroutine atm_final_mct
656 
657 !================================================================================
658 
659  subroutine atm_setgsmap_mct( mpicom_atm, ATMID, GSMap_atm )
660  use phys_grid, only : get_nlcols_p
661  !-------------------------------------------------------------------
662  !
663  ! Arguments
664  !
665  integer , intent(in) :: mpicom_atm
666  integer , intent(in) :: atmid
667  type(mct_gsmap), intent(out) :: gsmap_atm
668  !
669  ! Local variables
670  !
671  integer, allocatable :: gindex(:)
672  integer :: i, n, c, ncols, sizebuf, nlcols
673  integer :: ier ! error status
674  !-------------------------------------------------------------------
675 
676  ! Build the atmosphere grid numbering for MCT
677  ! NOTE: Numbering scheme is: West to East and South to North
678  ! starting at south pole. Should be the same as what's used in SCRIP
679 
680  ! Determine global seg map
681 
682  sizebuf=0
683  do c = begchunk, endchunk
684  ncols = get_ncols_p(c)
685  do i = 1,ncols
686  sizebuf = sizebuf+1
687  end do
688  end do
689 
690  allocate(gindex(sizebuf))
691 
692  n=0
693  do c = begchunk, endchunk
694  ncols = get_ncols_p(c)
695  do i = 1,ncols
696  n=n+1
697  gindex(n) = get_gcol_p(c,i)
698  end do
699  end do
700 
701  nlcols = get_nlcols_p()
702  call mct_gsmap_init( gsmap_atm, gindex, mpicom_atm, atmid, nlcols, ngcols)
703 
704  deallocate(gindex)
705 
706  end subroutine atm_setgsmap_mct
707 
708 !===============================================================================
709 
710  subroutine atm_import_mct( x2a_a, cam_in )
711 
712  !-----------------------------------------------------------------------
713  !
714  ! Uses
715  !
716  use dust_intr, only: dust_idx1
717 #if (defined MODAL_AERO)
718  use mo_chem_utls, only: get_spc_ndx
719 #endif
720  use shr_const_mod, only: shr_const_stebol
721  use seq_drydep_mod,only: n_drydep
722  !
723  ! Arguments
724  !
725  type(mct_avect), intent(inout) :: x2a_a
726  type(cam_in_t), intent(inout) :: cam_in(begchunk:endchunk)
727  !
728  ! Local variables
729  !
730  integer :: i,lat,n,c,ig ! indices
731  integer :: ncols ! number of columns
732  integer :: dust_ndx
733  logical, save :: first_time = .true.
734 
735 #if (defined MODAL_AERO)
736  integer, parameter:: ndst =2
737  integer, target :: spc_ndx(ndst)
738 #if (defined MODAL_AERO_7MODE)
739  integer, pointer :: dst_a5_ndx, dst_a7_ndx
740 #elif (defined MODAL_AERO_3MODE)
741  integer, pointer :: dst_a1_ndx, dst_a3_ndx
742 #endif
743 #endif
744  !-----------------------------------------------------------------------
745  !
746 #if (defined MODAL_AERO)
747 #if (defined MODAL_AERO_7MODE)
748  dst_a5_ndx => spc_ndx(1)
749  dst_a7_ndx => spc_ndx(2)
750  dst_a5_ndx = get_spc_ndx( 'dst_a5' )
751  dst_a7_ndx = get_spc_ndx( 'dst_a7' )
752 #elif (defined MODAL_AERO_3MODE)
753  dst_a1_ndx => spc_ndx(1)
754  dst_a3_ndx => spc_ndx(2)
755  dst_a1_ndx = get_spc_ndx( 'dst_a1' )
756  dst_a3_ndx = get_spc_ndx( 'dst_a3' )
757 #endif
758 #endif
759 
760  ! ccsm sign convention is that fluxes are positive downward
761 
762  ig=1
763  do c=begchunk,endchunk
764  ncols = get_ncols_p(c)
765 
766  ! initialize constituent surface fluxes to zero
767  cam_in(c)%cflx(:,:) = 0._r8
768 
769  do i =1,ncols
770  cam_in(c)%wsx(i) = -x2a_a%rAttr(index_x2a_faxx_taux,ig)
771  cam_in(c)%wsy(i) = -x2a_a%rAttr(index_x2a_faxx_tauy,ig)
772  cam_in(c)%lhf(i) = -x2a_a%rAttr(index_x2a_faxx_lat, ig)
773  cam_in(c)%shf(i) = -x2a_a%rAttr(index_x2a_faxx_sen, ig)
774  cam_in(c)%lwup(i) = -x2a_a%rAttr(index_x2a_faxx_lwup,ig)
775  cam_in(c)%cflx(i,1) = -x2a_a%rAttr(index_x2a_faxx_evap,ig)
776  cam_in(c)%asdir(i) = x2a_a%rAttr(index_x2a_sx_avsdr, ig)
777  cam_in(c)%aldir(i) = x2a_a%rAttr(index_x2a_sx_anidr, ig)
778  cam_in(c)%asdif(i) = x2a_a%rAttr(index_x2a_sx_avsdf, ig)
779  cam_in(c)%aldif(i) = x2a_a%rAttr(index_x2a_sx_anidf, ig)
780  cam_in(c)%ts(i) = x2a_a%rAttr(index_x2a_sx_t, ig)
781  cam_in(c)%sst(i) = x2a_a%rAttr(index_x2a_so_t, ig)
782  cam_in(c)%snowhland(i) = x2a_a%rAttr(index_x2a_sl_snowh, ig)
783  cam_in(c)%snowhice(i) = x2a_a%rAttr(index_x2a_si_snowh, ig)
784  cam_in(c)%tref(i) = x2a_a%rAttr(index_x2a_sx_tref, ig)
785  cam_in(c)%qref(i) = x2a_a%rAttr(index_x2a_sx_qref, ig)
786  cam_in(c)%u10(i) = x2a_a%rAttr(index_x2a_sx_u10, ig)
787  cam_in(c)%icefrac(i) = x2a_a%rAttr(index_x2a_sf_ifrac, ig)
788  cam_in(c)%ocnfrac(i) = x2a_a%rAttr(index_x2a_sf_ofrac, ig)
789  cam_in(c)%landfrac(i) = x2a_a%rAttr(index_x2a_sf_lfrac, ig)
790  if ( associated(cam_in(c)%ram1) ) &
791  cam_in(c)%ram1(i) = x2a_a%rAttr(index_x2a_sl_ram1 , ig)
792  if ( associated(cam_in(c)%fv) ) &
793  cam_in(c)%fv(i) = x2a_a%rAttr(index_x2a_sl_fv , ig)
794  if ( associated(cam_in(c)%soilw) ) &
795  cam_in(c)%soilw(i) = x2a_a%rAttr(index_x2a_sl_soilw, ig)
796  dust_ndx = dust_idx1()
797  ! check that dust constituents are actually in the simulation
798  if (dust_ndx>0) then
799 #if (defined MODAL_AERO)
800 #if (defined MODAL_AERO_7MODE)
801  cam_in(c)%cflx(i,dust_ndx ) = 0.13_r8 & ! 1st mode, based on Zender et al (2003) Table 1
802 #elif (defined MODAL_AERO_3MODE)
803  cam_in(c)%cflx(i,dust_ndx ) = 0.032_r8 & ! 1st mode, based on Zender et al (2003) Table 1
804 #endif
805  * (-x2a_a%rAttr(index_x2a_fall_flxdst1, ig) &
806  -x2a_a%rAttr(index_x2a_fall_flxdst2, ig) &
807  -x2a_a%rAttr(index_x2a_fall_flxdst3, ig) &
808  -x2a_a%rAttr(index_x2a_fall_flxdst4, ig))
809 #if (defined MODAL_AERO_7MODE)
810  cam_in(c)%cflx(i,dust_ndx-spc_ndx(1)+spc_ndx(2)) = 0.87_r8 & ! 2nd mode
811 #elif (defined MODAL_AERO_3MODE)
812  cam_in(c)%cflx(i,dust_ndx-spc_ndx(1)+spc_ndx(2)) = 0.968_r8 & ! 2nd mode
813 #endif
814  * (-x2a_a%rAttr(index_x2a_fall_flxdst1, ig) &
815  -x2a_a%rAttr(index_x2a_fall_flxdst2, ig) &
816  -x2a_a%rAttr(index_x2a_fall_flxdst3, ig) &
817  -x2a_a%rAttr(index_x2a_fall_flxdst4, ig))
818 #else
819  cam_in(c)%cflx(i,dust_ndx ) = -x2a_a%rAttr(index_x2a_fall_flxdst1, ig)
820  cam_in(c)%cflx(i,dust_ndx +1) = -x2a_a%rAttr(index_x2a_fall_flxdst2, ig)
821  cam_in(c)%cflx(i,dust_ndx +2) = -x2a_a%rAttr(index_x2a_fall_flxdst3, ig)
822  cam_in(c)%cflx(i,dust_ndx +3) = -x2a_a%rAttr(index_x2a_fall_flxdst4, ig)
823 #endif
824  endif
825 
826  ! dry dep velocities
827  if ( index_x2a_sl_ddvel/=0 .and. n_drydep>0 ) then
828  cam_in(c)%depvel(i,:n_drydep) = &
829  x2a_a%rAttr(index_x2a_sl_ddvel:index_x2a_sl_ddvel+n_drydep-1, ig)
830  endif
831  !
832  ! fields needed to calculate water isotopes to ocean evaporation processes
833  !
834  cam_in(c)%ustar(i) = x2a_a%rAttr(index_x2a_so_ustar,ig)
835  cam_in(c)%re(i) = x2a_a%rAttr(index_x2a_so_re ,ig)
836  cam_in(c)%ssq(i) = x2a_a%rAttr(index_x2a_so_ssq ,ig)
837  !
838  ! bgc scenarios
839  !
840  if (index_x2a_fall_fco2_lnd /= 0) then
841  cam_in(c)%fco2_lnd(i) = -x2a_a%rAttr(index_x2a_fall_fco2_lnd,ig)
842  end if
843  if (index_x2a_faoo_fco2_ocn /= 0) then
844  cam_in(c)%fco2_ocn(i) = -x2a_a%rAttr(index_x2a_faoo_fco2_ocn,ig)
845  end if
846  if (index_x2a_faoo_fdms_ocn /= 0) then
847  cam_in(c)%fdms(i) = -x2a_a%rAttr(index_x2a_faoo_fdms_ocn,ig)
848  end if
849 
850  ig=ig+1
851 
852  end do
853  end do
854 
855  ! Get total co2 flux from components,
856  ! Note - co2_transport determines if cam_in(c)%cflx(i,c_i(1:4)) is allocated
857 
858  if (co2_transport()) then
859 
860  ! Interpolate in time for flux data read in
861  if (co2_readflux_ocn) then
862  call co2_time_interp_ocn
863  end if
864  if (co2_readflux_fuel) then
865  call co2_time_interp_fuel
866  end if
867 
868  ! from ocn : data read in or from coupler or zero
869  ! from fuel: data read in or zero
870  ! from lnd : through coupler or zero
871  do c=begchunk,endchunk
872  ncols = get_ncols_p(c)
873  do i=1,ncols
874 
875  ! all co2 fluxes in unit kgCO2/m2/s ! co2 flux from ocn
876  if (index_x2a_faoo_fco2_ocn /= 0) then
877  cam_in(c)%cflx(i,c_i(1)) = cam_in(c)%fco2_ocn(i)
878  else if (co2_readflux_ocn) then
879  ! convert from molesCO2/m2/s to kgCO2/m2/s
880  cam_in(c)%cflx(i,c_i(1)) = &
881  -data_flux_ocn%co2flx(i,c)*(1._r8- cam_in(c)%landfrac(i)) &
882  *mwco2*1.0e-3_r8
883  else
884  cam_in(c)%cflx(i,c_i(1)) = 0._r8
885  end if
886 
887  ! co2 flux from fossil fuel
888  if (co2_readflux_fuel) then
889  cam_in(c)%cflx(i,c_i(2)) = data_flux_fuel%co2flx(i,c)
890  else
891  cam_in(c)%cflx(i,c_i(2)) = 0._r8
892  end if
893 
894  ! co2 flux from land (cpl already multiplies flux by land fraction)
895  if (index_x2a_fall_fco2_lnd /= 0) then
896  cam_in(c)%cflx(i,c_i(3)) = cam_in(c)%fco2_lnd(i)
897  else
898  cam_in(c)%cflx(i,c_i(3)) = 0._r8
899  end if
900 
901  ! merged co2 flux
902  cam_in(c)%cflx(i,c_i(4)) = cam_in(c)%cflx(i,c_i(1)) + &
903  cam_in(c)%cflx(i,c_i(2)) + &
904  cam_in(c)%cflx(i,c_i(3))
905  end do
906  end do
907  end if
908  !
909  ! if first step, determine longwave up flux from the surface temperature
910  !
911  if (first_time) then
912  if (is_first_step()) then
913  do c=begchunk, endchunk
914  ncols = get_ncols_p(c)
915  do i=1,ncols
916  cam_in(c)%lwup(i) = shr_const_stebol*(cam_in(c)%ts(i)**4)
917  end do
918  end do
919  end if
920  first_time = .false.
921  end if
922 
923  end subroutine atm_import_mct
924 
925 !===============================================================================
926 
927  subroutine atm_export_mct( cam_out, a2x_a )
928 
929  !-------------------------------------------------------------------
930  !
931  ! Arguments
932  !
933  type(cam_out_t), intent(in) :: cam_out(begchunk:endchunk)
934  type(mct_avect), intent(inout) :: a2x_a
935  !
936  ! Local variables
937  !
938  integer :: avsize, avnat
939  integer :: i,m,c,n,ig ! indices
940  integer :: ncols ! Number of columns
941  !-----------------------------------------------------------------------
942 
943  ! Copy from component arrays into chunk array data structure
944  ! Rearrange data from chunk structure into lat-lon buffer and subsequently
945  ! create attribute vector
946 
947  ig=1
948  do c=begchunk, endchunk
949  ncols = get_ncols_p(c)
950  do i=1,ncols
951  a2x_a%rAttr(index_a2x_sa_pslv ,ig) = cam_out(c)%psl(i)
952  a2x_a%rAttr(index_a2x_sa_z ,ig) = cam_out(c)%zbot(i)
953  a2x_a%rAttr(index_a2x_sa_u ,ig) = cam_out(c)%ubot(i)
954  a2x_a%rAttr(index_a2x_sa_v ,ig) = cam_out(c)%vbot(i)
955  a2x_a%rAttr(index_a2x_sa_tbot ,ig) = cam_out(c)%tbot(i)
956  a2x_a%rAttr(index_a2x_sa_ptem ,ig) = cam_out(c)%thbot(i)
957  a2x_a%rAttr(index_a2x_sa_pbot ,ig) = cam_out(c)%pbot(i)
958  a2x_a%rAttr(index_a2x_sa_shum ,ig) = cam_out(c)%qbot(i,1)
959  a2x_a%rAttr(index_a2x_sa_dens ,ig) = cam_out(c)%rho(i)
960  a2x_a%rAttr(index_a2x_faxa_swnet,ig) = cam_out(c)%netsw(i)
961  a2x_a%rAttr(index_a2x_faxa_lwdn ,ig) = cam_out(c)%flwds(i)
962  a2x_a%rAttr(index_a2x_faxa_rainc,ig) = (cam_out(c)%precc(i)-cam_out(c)%precsc(i))*1000._r8
963  a2x_a%rAttr(index_a2x_faxa_rainl,ig) = (cam_out(c)%precl(i)-cam_out(c)%precsl(i))*1000._r8
964  a2x_a%rAttr(index_a2x_faxa_snowc,ig) = cam_out(c)%precsc(i)*1000._r8
965  a2x_a%rAttr(index_a2x_faxa_snowl,ig) = cam_out(c)%precsl(i)*1000._r8
966  a2x_a%rAttr(index_a2x_faxa_swndr,ig) = cam_out(c)%soll(i)
967  a2x_a%rAttr(index_a2x_faxa_swvdr,ig) = cam_out(c)%sols(i)
968  a2x_a%rAttr(index_a2x_faxa_swndf,ig) = cam_out(c)%solld(i)
969  a2x_a%rAttr(index_a2x_faxa_swvdf,ig) = cam_out(c)%solsd(i)
970 
971  ! aerosol deposition fluxes
972  a2x_a%rAttr(index_a2x_faxa_bcphidry,ig) = cam_out(c)%bcphidry(i)
973  a2x_a%rAttr(index_a2x_faxa_bcphodry,ig) = cam_out(c)%bcphodry(i)
974  a2x_a%rAttr(index_a2x_faxa_bcphiwet,ig) = cam_out(c)%bcphiwet(i)
975  a2x_a%rAttr(index_a2x_faxa_ocphidry,ig) = cam_out(c)%ocphidry(i)
976  a2x_a%rAttr(index_a2x_faxa_ocphodry,ig) = cam_out(c)%ocphodry(i)
977  a2x_a%rAttr(index_a2x_faxa_ocphiwet,ig) = cam_out(c)%ocphiwet(i)
978  a2x_a%rAttr(index_a2x_faxa_dstwet1,ig) = cam_out(c)%dstwet1(i)
979  a2x_a%rAttr(index_a2x_faxa_dstdry1,ig) = cam_out(c)%dstdry1(i)
980  a2x_a%rAttr(index_a2x_faxa_dstwet2,ig) = cam_out(c)%dstwet2(i)
981  a2x_a%rAttr(index_a2x_faxa_dstdry2,ig) = cam_out(c)%dstdry2(i)
982  a2x_a%rAttr(index_a2x_faxa_dstwet3,ig) = cam_out(c)%dstwet3(i)
983  a2x_a%rAttr(index_a2x_faxa_dstdry3,ig) = cam_out(c)%dstdry3(i)
984  a2x_a%rAttr(index_a2x_faxa_dstwet4,ig) = cam_out(c)%dstwet4(i)
985  a2x_a%rAttr(index_a2x_faxa_dstdry4,ig) = cam_out(c)%dstdry4(i)
986 
987  if (index_a2x_sa_co2prog /= 0) then
988  a2x_a%rAttr(index_a2x_sa_co2prog,ig) = cam_out(c)%co2prog(i) ! atm prognostic co2
989  end if
990  if (index_a2x_sa_co2diag /= 0) then
991  a2x_a%rAttr(index_a2x_sa_co2diag,ig) = cam_out(c)%co2diag(i) ! atm diagnostic co2
992  end if
993 
994  ig=ig+1
995  end do
996  end do
997 
998  end subroutine atm_export_mct
999 
1000 !===============================================================================
1001 
1002  subroutine atm_domain_mct( lsize, gsMap_a, dom_a )
1003 
1004  !-------------------------------------------------------------------
1005  !
1006  ! Arguments
1007  !
1008  integer , intent(in) :: lsize
1009  type(mct_gsmap), intent(in) :: gsmap_a
1010  type(mct_ggrid), intent(inout):: dom_a
1011  !
1012  ! Local Variables
1013  !
1014  integer :: n,i,c,ncols ! indices
1015  real(r8) :: lats(pcols) ! array of chunk latitudes
1016  real(r8) :: lons(pcols) ! array of chunk longitude
1017  real(r8) :: area(pcols) ! area in radians squared for each grid point
1018  real(r8), pointer :: data(:) ! temporary
1019  integer , pointer :: idata(:) ! temporary
1020  real(r8), parameter:: radtodeg = 180.0_r8/shr_const_pi
1021  !-------------------------------------------------------------------
1022  !
1023  ! Initialize mct atm domain
1024  !
1025  call mct_ggrid_init( ggrid=dom_a, coordchars=trim(seq_flds_dom_coord), otherchars=trim(seq_flds_dom_other), lsize=lsize )
1026  !
1027  ! Allocate memory
1028  !
1029  allocate(data(lsize))
1030  !
1031  ! Initialize attribute vector with special value
1032  !
1033  call mct_gsmap_orderedpoints(gsmap_a, iam, idata)
1034  call mct_ggrid_importiattr(dom_a,'GlobGridNum',idata,lsize)
1035  !
1036  ! Determine domain (numbering scheme is: West to East and South to North to South pole)
1037  ! Initialize attribute vector with special value
1038  !
1039  data(:) = -9999.0_r8
1040  call mct_ggrid_importrattr(dom_a,"lat" ,data,lsize)
1041  call mct_ggrid_importrattr(dom_a,"lon" ,data,lsize)
1042  call mct_ggrid_importrattr(dom_a,"area" ,data,lsize)
1043  call mct_ggrid_importrattr(dom_a,"aream",data,lsize)
1044  data(:) = 0.0_r8
1045  call mct_ggrid_importrattr(dom_a,"mask" ,data,lsize)
1046  data(:) = 1.0_r8
1047  call mct_ggrid_importrattr(dom_a,"frac" ,data,lsize)
1048  !
1049  ! Fill in correct values for domain components
1050  !
1051  n=0
1052  do c = begchunk, endchunk
1053  ncols = get_ncols_p(c)
1054  call get_rlat_all_p(c, ncols, lats)
1055  do i=1,ncols
1056  n = n+1
1057  data(n) = lats(i)*radtodeg
1058  end do
1059  end do
1060  call mct_ggrid_importrattr(dom_a,"lat",data,lsize)
1061 
1062  n=0
1063  do c = begchunk, endchunk
1064  ncols = get_ncols_p(c)
1065  call get_rlon_all_p(c, ncols, lons)
1066  do i=1,ncols
1067  n = n+1
1068  data(n) = lons(i)*radtodeg
1069  end do
1070  end do
1071  call mct_ggrid_importrattr(dom_a,"lon",data,lsize)
1072 
1073  n=0
1074  do c = begchunk, endchunk
1075  ncols = get_ncols_p(c)
1076  call get_area_all_p(c, ncols, area)
1077  do i=1,ncols
1078  n = n+1
1079  data(n) = area(i)
1080  end do
1081  end do
1082  call mct_ggrid_importrattr(dom_a,"area",data,lsize)
1083 
1084  n=0
1085  do c = begchunk, endchunk
1086  ncols = get_ncols_p(c)
1087  do i=1,ncols
1088  n = n+1
1089  data(n) = 1._r8 ! mask
1090  end do
1091  end do
1092  call mct_ggrid_importrattr(dom_a,"mask" ,data,lsize)
1093  deallocate(data)
1094 
1095  end subroutine atm_domain_mct
1096 
1097 !===========================================================================================
1098 !
1099  subroutine atm_read_srfrest_mct( EClock, cdata_a, x2a_a, a2x_a)
1100  use cam_pio_utils
1101  !-----------------------------------------------------------------------
1102  !
1103  ! Arguments
1104  !
1105  type(esmf_clock),intent(in) :: eclock
1106  type(seq_cdata), intent(inout) :: cdata_a
1107  type(mct_avect), intent(inout) :: x2a_a
1108  type(mct_avect), intent(inout) :: a2x_a
1109  !
1110  ! Local variables
1111  !
1112  integer :: npts ! array size
1113  integer :: rcode ! return error code
1114  type(mct_avect) :: gdata ! global/gathered bundle data
1115  integer :: yr_spec ! Current year
1116  integer :: mon_spec ! Current month
1117  integer :: day_spec ! Current day
1118  integer :: sec_spec ! Current time of day (sec)
1119  !-----------------------------------------------------------------------
1120  !
1121  ! Determine and open surface restart dataset
1122  !
1123  integer, pointer :: dof(:)
1124  integer :: lnx, nf_x2a, nf_a2x, k
1125  real(r8), allocatable :: tmp(:)
1126  type(file_desc_t) :: file
1127  type(io_desc_t) :: iodesc
1128  type(var_desc_t) :: varid
1129  character(CL) :: itemc ! string converted to char
1130  type(mct_string) :: mstring ! mct char type
1131 
1132 
1133 
1134  call seq_timemgr_eclockgetdata( eclock, curr_yr=yr_spec,curr_mon=mon_spec, &
1135  curr_day=day_spec, curr_tod=sec_spec )
1136  fname_srf_cam = interpret_filename_spec( rsfilename_spec_cam, case=get_restcase(), &
1137  yr_spec=yr_spec, mon_spec=mon_spec, day_spec=day_spec, sec_spec= sec_spec )
1138  pname_srf_cam = trim(get_restartdir() )//fname_srf_cam
1139  call getfil(pname_srf_cam, fname_srf_cam)
1140 
1141  call cam_pio_openfile(file, fname_srf_cam, 0)
1142  call mct_gsmap_orderedpoints(cdata_a%gsmap, iam, dof)
1143  lnx = mct_gsmap_gsize(cdata_a%gsmap)
1144  call pio_initdecomp(pio_subsystem, pio_double, (/lnx/), dof, iodesc)
1145  allocate(tmp(size(dof)))
1146  deallocate(dof)
1147 
1148  nf_x2a = mct_avect_nrattr(x2a_a)
1149 
1150  do k=1,nf_x2a
1151  call mct_avect_getrlist(mstring,k,x2a_a)
1152  itemc = mct_string_tochar(mstring)
1153  call mct_string_clean(mstring)
1154 
1155  call pio_seterrorhandling(file, pio_bcast_error)
1156  rcode = pio_inq_varid(file,'x2a_'//trim(itemc) ,varid)
1157  if (rcode == pio_noerr) then
1158  call pio_read_darray(file, varid, iodesc, tmp, rcode)
1159  x2a_a%rattr(k,:) = tmp(:)
1160  else
1161  if (masterproc) then
1162  write(iulog,*)'srfrest warning: field ',trim(itemc),' is not on restart file'
1163  write(iulog,*)'for backwards compatibility will set it to 0'
1164  end if
1165  x2a_a%rattr(k,:) = 0._r8
1166  end if
1167  call pio_seterrorhandling(file, pio_internal_error)
1168  end do
1169 
1170  nf_a2x = mct_avect_nrattr(a2x_a)
1171 
1172  do k=1,nf_a2x
1173  call mct_avect_getrlist(mstring,k,a2x_a)
1174  itemc = mct_string_tochar(mstring)
1175  call mct_string_clean(mstring)
1176 
1177  rcode = pio_inq_varid(file,'a2x_'//trim(itemc) ,varid)
1178  call pio_read_darray(file, varid, iodesc, tmp, rcode)
1179  a2x_a%rattr(k,:) = tmp(:)
1180  end do
1181 
1182  call pio_freedecomp(file,iodesc)
1183  call pio_closefile(file)
1184  deallocate(tmp)
1185 
1186  end subroutine atm_read_srfrest_mct
1187 !
1188 !===========================================================================================
1189 !
1190  subroutine atm_write_srfrest_mct( cdata_a, x2a_a, a2x_a, &
1191  yr_spec, mon_spec, day_spec, sec_spec)
1192  use cam_pio_utils
1193  !-----------------------------------------------------------------------
1194  !
1195  ! Arguments
1196  !
1197  type(seq_cdata), intent(in) :: cdata_a
1198  type(mct_avect), intent(in) :: x2a_a
1199  type(mct_avect), intent(in) :: a2x_a
1200  integer , intent(in) :: yr_spec ! Simulation year
1201  integer , intent(in) :: mon_spec ! Simulation month
1202  integer , intent(in) :: day_spec ! Simulation day
1203  integer , intent(in) :: sec_spec ! Seconds into current simulation day
1204  !
1205  ! Local variables
1206  !
1207  integer :: rcode ! return error code
1208  type(mct_avect) :: gdata ! global/gathered bundle data
1209  !-----------------------------------------------------------------------
1210  !
1211  ! Determine and open surface restart dataset
1212  !
1213 
1214  integer, pointer :: dof(:)
1215  integer :: nf_x2a, nf_a2x, lnx, dimid(1), k
1216  type(file_desc_t) :: file
1217  type(var_desc_t), pointer :: varid_x2a(:), varid_a2x(:)
1218  type(io_desc_t) :: iodesc
1219  character(CL) :: itemc ! string converted to char
1220  type(mct_string) :: mstring ! mct char type
1221 
1222 
1223  fname_srf_cam = interpret_filename_spec( rsfilename_spec_cam, &
1224  yr_spec=yr_spec, mon_spec=mon_spec, day_spec=day_spec, sec_spec= sec_spec )
1225  call cam_pio_createfile(file, fname_srf_cam, 0)
1226 
1227  call mct_gsmap_orderedpoints(cdata_a%gsmap, iam, dof)
1228  lnx = mct_gsmap_gsize(cdata_a%gsmap)
1229  call pio_initdecomp(pio_subsystem, pio_double, (/lnx/), dof, iodesc)
1230 
1231  deallocate(dof)
1232 
1233  nf_x2a = mct_avect_nrattr(x2a_a)
1234  allocate(varid_x2a(nf_x2a))
1235 
1236  rcode = pio_def_dim(file,'x2a_nx',lnx,dimid(1))
1237  do k = 1,nf_x2a
1238  call mct_avect_getrlist(mstring,k,x2a_a)
1239  itemc = mct_string_tochar(mstring)
1240  call mct_string_clean(mstring)
1241  rcode = pio_def_var(file,'x2a_'//trim(itemc),pio_double,dimid,varid_x2a(k))
1242  rcode = pio_put_att(file,varid_x2a(k),"_fillvalue",fillvalue)
1243  enddo
1244 
1245  nf_a2x = mct_avect_nrattr(a2x_a)
1246  allocate(varid_a2x(nf_a2x))
1247 
1248  rcode = pio_def_dim(file,'a2x_nx',lnx,dimid(1))
1249  do k = 1,nf_a2x
1250  call mct_avect_getrlist(mstring,k,a2x_a)
1251  itemc = mct_string_tochar(mstring)
1252  call mct_string_clean(mstring)
1253  rcode = pio_def_var(file,'a2x_'//trim(itemc),pio_double,dimid,varid_a2x(k))
1254  rcode = pio_put_att(file,varid_a2x(k),"_fillvalue",fillvalue)
1255  enddo
1256 
1257  rcode = pio_enddef(file) ! don't check return code, might be enddef already
1258 
1259 
1260  do k=1,nf_x2a
1261  call pio_write_darray(file, varid_x2a(k), iodesc, x2a_a%rattr(k,:), rcode)
1262  end do
1263 
1264  do k=1,nf_a2x
1265  call pio_write_darray(file, varid_a2x(k), iodesc, a2x_a%rattr(k,:), rcode)
1266  end do
1267 
1268  deallocate(varid_x2a, varid_a2x)
1269 
1270  call pio_freedecomp(file,iodesc)
1271  call pio_closefile(file)
1272 
1273 
1274  end subroutine atm_write_srfrest_mct
1275 
1276 !================================================================================
1277 
1278 end module atm_comp_mct
subroutine, public atm_final_mct(EClock, cdata_a, x2a_a, a2x_a)
subroutine, public cam_init(cam_out, cam_in, mpicom_atm, start_ymd, start_tod, ref_ymd, ref_tod, stop_ymd, stop_tod, perpetual_run, perpetual_ymd, calendar)
Definition: cam_comp.F90:73
subroutine, public cam_final(cam_out, cam_in)
Definition: cam_comp.F90:447
subroutine, public cam_run2(cam_out, cam_in)
Definition: cam_comp.F90:269
subroutine, public cam_run1(cam_in, cam_out)
Definition: cam_comp.F90:210
subroutine, public atm_run_mct(EClock, cdata_a, x2a_a, a2x_a)
subroutine, public cam_run3(cam_out)
Definition: cam_comp.F90:322
subroutine, public atm_init_mct(EClock, cdata_a, x2a_a, a2x_a, NLFilename)
subroutine, public cam_run4(cam_out, cam_in, rstwr, nlend, yr_spec, mon_spec, day_spec, sec_spec)
Definition: cam_comp.F90:361
CAM export state.
Definition: camsrfexch.F90:34
CAM import state.
Definition: camsrfexch.F90:80