!=============================================================================== ! SVN $Id: seq_rest_mod.F90 18683 2009-09-30 22:20:22Z kauff $ ! SVN $URL: https://svn-ccsm-models.cgd.ucar.edu/drv/seq_mct/branch_tags/cesm1_0_rel_tags/cesm1_0_rel01_drvseq3_1_32/driver/seq_rest_mod.F90 $ !=============================================================================== !BOP =========================================================================== ! ! !MODULE: seq_rest_mod -- cpl7 restart reading/writing routines ! ! !DESCRIPTION: ! ! Reads & writes cpl7 restart files ! ! !REMARKS: ! ! aVect, domain, and fraction info accessed via seq_avdata_mod ! to avoid excessively long routine arg lists. ! ! !REVISION HISTORY: ! 2009-Sep-25 - B. Kauffman - move from cpl7 main program into rest module ! 2007-mmm-dd - T. Craig - initial restart functionality ! ! !INTERFACE: ------------------------------------------------------------------ module seq_rest_mod 1,14 #define NEW_BUDGET ! !USES: use shr_kind_mod, only: R8 => SHR_KIND_R8, IN => SHR_KIND_IN use shr_kind_mod, only: CL => SHR_KIND_CL, CS => SHR_KIND_CS use shr_sys_mod, only: shr_sys_abort, shr_sys_flush use shr_mpi_mod, only : shr_mpi_bcast use shr_cal_mod, only: shr_cal_date2ymd use mct_mod ! adds mct_ prefix to mct lib use ESMF_Mod use seq_avdata_mod ! drv aVects & associated domain, fract, cdata (public read/write data) use seq_diag_mct ! diagnostic routines (public read/write data) use seq_comm_mct ! Sets mpi communicators, logunit and loglevel use seq_cdata_mod ! "cdata" type & methods (domain + decomp + infodata in one datatype) use seq_infodata_mod ! "infodata" gathers various control flags into one datatype use seq_timemgr_mod ! clock & alarm routines use seq_io_mod ! lower level io routines implicit none private ! !PUBLIC TYPES: ! no public types ! !PUBLIC MEMBER FUNCTIONS public :: seq_rest_read ! read cpl7 restart data public :: seq_rest_write ! write cpl7 restart data ! !PUBLIC DATA MEMBERS: ! no public data !EOP !---------------------------------------------------------------------------- ! local data !---------------------------------------------------------------------------- logical :: iamin_CPLID ! pe associated with CPLID integer(IN) :: mpicom_GLOID ! MPI global communicator integer(IN) :: mpicom_CPLID ! MPI cpl communicator integer(IN) :: nthreads_GLOID ! OMP global number of threads integer(IN) :: nthreads_CPLID ! OMP cpl number of threads logical :: drv_threading ! driver threading control logical :: atm_present ! .true. => atm is present logical :: lnd_present ! .true. => land is present logical :: ice_present ! .true. => ice is present logical :: ocn_present ! .true. => ocn is present logical :: rof_present ! .true. => land runoff is present logical :: glc_present ! .true. => glc is present logical :: sno_present ! .true. => land sno is present logical :: atm_prognostic ! .true. => atm comp expects input logical :: lnd_prognostic ! .true. => lnd comp expects input logical :: ice_prognostic ! .true. => ice comp expects input logical :: ocn_prognostic ! .true. => ocn comp expects input logical :: ocnrof_prognostic ! .true. => ocn comp expects runoff input logical :: glc_prognostic ! .true. => glc comp expects input logical :: sno_prognostic ! .true. => sno comp expects input integer(IN) :: info_debug = 0 ! local info_debug level !=============================================================================== contains !=============================================================================== subroutine seq_rest_read(rest_file) 1,26 implicit none character(*),intent(in) :: rest_file ! restart file path/name integer(IN) :: n,n1,n2,n3 real(r8),allocatable :: ds(:) ! for reshaping diag data for restart file real(r8),allocatable :: ns(:) ! for reshaping diag data for restart file character(CS) :: string integer(IN) :: ierr ! MPI error return !------------------------------------------------------------------------------- ! !------------------------------------------------------------------------------- !---------------------------------------------------------------------------- ! get required infodata !---------------------------------------------------------------------------- iamin_CPLID = seq_comm_iamin(CPLID) call seq_comm_setptrs(GLOID,mpicom=mpicom_GLOID,nthreads=nthreads_GLOID) call seq_comm_setptrs(CPLID,mpicom=mpicom_CPLID,nthreads=nthreads_CPLID) call seq_infodata_getData(infodata,drv_threading=drv_threading) call seq_infodata_getData(infodata, & atm_present=atm_present, & lnd_present=lnd_present, & rof_present=rof_present, & ice_present=ice_present, & ocn_present=ocn_present, & glc_present=glc_present, & sno_present=sno_present ) call seq_infodata_getData(infodata, & atm_prognostic=atm_prognostic, & lnd_prognostic=lnd_prognostic, & ice_prognostic=ice_prognostic, & ocn_prognostic=ocn_prognostic, & ocnrof_prognostic=ocnrof_prognostic, & glc_prognostic=glc_prognostic, & sno_prognostic=sno_prognostic ) if (iamin_CPLID) then if (drv_threading) call seq_comm_setnthreads(nthreads_CPLID) if (atm_present) then call seq_io_read(rest_file,cdata_ax,fractions_ax,'fractions_ax') call seq_io_read(rest_file,cdata_ax,a2x_ax,'a2x_ax') endif if (lnd_present) then call seq_io_read(rest_file,cdata_lx,fractions_lx,'fractions_lx') call seq_io_read(rest_file,cdata_lx,l2x_lx,'l2x_lx') endif if (ocn_present) then call seq_io_read(rest_file,cdata_ox,fractions_ox,'fractions_ox') call seq_io_read(rest_file,cdata_ox,o2x_ox,'o2x_ox') call seq_io_read(rest_file,cdata_ox,x2oacc_ox%data,'x2oacc_ox') ! call seq_io_read(rest_file,cdata_ox,x2oacc_ox%steps_done,'x2oacc_ox_cnt') call seq_io_read(rest_file,cdata_ox,x2oacc_ox_cnt,'x2oacc_ox_cnt') call seq_io_read(rest_file,cdata_ox,xao_ox,'xao_ox') call seq_io_read(rest_file,cdata_ax,xao_ax,'xao_ax') endif if (ice_present) then call seq_io_read(rest_file,cdata_ix,fractions_ix,'fractions_ix') call seq_io_read(rest_file,cdata_ix,i2x_ix,'i2x_ix') endif if (rof_present .and. ocnrof_prognostic) then call seq_io_read(rest_file,cdata_rx,r2xacc_rx%data,'r2xacc_rx') call seq_io_read(rest_file,cdata_rx,r2xacc_rx_cnt,'r2xacc_rx_cnt') endif if (glc_present) then call seq_io_read(rest_file,cdata_gx,fractions_gx,'fractions_gx') endif if (sno_present) then call seq_io_read(rest_file,cdata_sx,x2s_sx,'x2s_sx') endif #if (defined NEW_BUDGET) n = size(budg_dataG) allocate(ds(n),ns(n)) call seq_io_read(rest_file,cdata_ax,ds,'budg_dataG') call seq_io_read(rest_file,cdata_ax,ns,'budg_ns') n = 0 do n1 = 1,size(budg_dataG,dim=1) do n2 = 1,size(budg_dataG,dim=2) do n3 = 1,size(budg_dataG,dim=3) n = n + 1 budg_dataG(n1,n2,n3) = ds(n) budg_ns (n1,n2,n3) = ns(n) enddo enddo enddo ! call shr_mpi_bcast(budg_dataG,cpl_io_root) ! not necessary, io lib does bcast deallocate(ds,ns) #endif if (drv_threading) call seq_comm_setnthreads(nthreads_GLOID) endif end subroutine seq_rest_read !=============================================================================== subroutine seq_rest_write(EClock_d,seq_SyncClock) 1,37 implicit none type(ESMF_Clock) ,intent(in) :: EClock_d ! driver clock type(seq_timemgr_type),intent(inout) :: seq_SyncClock ! contains ptr to driver clock integer(IN) :: n,n1,n2,n3,fk integer(IN) :: curr_ymd ! Current date YYYYMMDD integer(IN) :: curr_tod ! Current time-of-day (s) integer(IN) :: yy,mm,dd ! year, month, day character(CL) :: case_name ! case name logical :: whead,wdata ! flags header/data writing logical :: cdf64 ! true => create netCDF with 64 bit addressing character(CL) :: rest_file ! Local path to restart filename integer(IN) :: ierr ! MPI error return real(r8),allocatable :: ds(:) ! for reshaping diag data for restart file real(r8),allocatable :: ns(:) ! for reshaping diag data for restart file !------------------------------------------------------------------------------- ! !------------------------------------------------------------------------------- !---------------------------------------------------------------------------- ! get required infodata !---------------------------------------------------------------------------- iamin_CPLID = seq_comm_iamin(CPLID) call seq_comm_setptrs(GLOID,mpicom=mpicom_GLOID,nthreads=nthreads_GLOID) call seq_comm_setptrs(CPLID,mpicom=mpicom_CPLID,nthreads=nthreads_CPLID) call seq_infodata_getData(infodata,drv_threading=drv_threading) call seq_infodata_getData(infodata, & atm_present=atm_present, & lnd_present=lnd_present, & rof_present=rof_present, & ice_present=ice_present, & ocn_present=ocn_present, & glc_present=glc_present, & sno_present=sno_present ) call seq_infodata_getData(infodata, & atm_prognostic=atm_prognostic, & lnd_prognostic=lnd_prognostic, & ice_prognostic=ice_prognostic, & ocn_prognostic=ocn_prognostic, & ocnrof_prognostic=ocnrof_prognostic, & glc_prognostic=glc_prognostic, & sno_prognostic=sno_prognostic ) call seq_infodata_getData(infodata, cpl_cdf64=cdf64 ) ! Write out infodata and time manager data to restart file call seq_infodata_GetData( infodata, case_name=case_name) call seq_timemgr_EClockGetData( EClock_d, curr_ymd=curr_ymd, curr_tod=curr_tod) call shr_cal_date2ymd(curr_ymd,yy,mm,dd) write(rest_file,"(2a,i4.4,a,i2.2,a,i2.2,a,i5.5,a)") & trim(case_name), '.cpl.r.', yy,'-',mm,'-',dd,'-',curr_tod,'.nc' call seq_infodata_Restart ('write',infodata ,rest_file,mpicom_cplid) call mpi_barrier(mpicom_CPLID,ierr) call seq_timemgr_clockRestart('write',seq_SyncClock,rest_file,mpicom_cplid) call mpi_barrier(mpicom_CPLID,ierr) ! Write driver data to restart file if (iamin_CPLID) then if (drv_threading) call seq_comm_setnthreads(nthreads_CPLID) #if (defined NEW_BUDGET) ! copy budg_dataG into 1d array n = size(budg_dataG) allocate(ds(n),ns(n)) call shr_mpi_bcast(budg_dataG,mpicom_CPLID) ! pio requires data on all pe's? n = 0 do n1 = 1,size(budg_dataG,dim=1) do n2 = 1,size(budg_dataG,dim=2) do n3 = 1,size(budg_dataG,dim=3) n = n + 1 ds(n) = budg_dataG(n1,n2,n3) ns(n) = budg_ns(n1,n2,n3) enddo enddo enddo #endif call seq_io_wopen(rest_file,cdata_ax,clobber=.false.,cdf64=cdf64) ! loop twice (for perf), first time write header, second time write data do fk = 1,2 if (fk == 1) then whead = .true. wdata = .false. call seq_io_redef(rest_file) elseif (fk == 2) then whead = .false. wdata = .true. call seq_io_enddef(rest_file) else call shr_sys_abort('driver_write_rstart fk illegal') end if #if (defined NEW_BUDGET) call seq_io_write(rest_file,cdata_ax,ds,'budg_dataG',whead=whead,wdata=wdata) call seq_io_write(rest_file,cdata_ax,ns,'budg_ns',whead=whead,wdata=wdata) #endif if (atm_present) then call seq_io_write(rest_file,cdata_ax,fractions_ax,'fractions_ax',whead=whead,wdata=wdata) call seq_io_write(rest_file,cdata_ax,a2x_ax,'a2x_ax',whead=whead,wdata=wdata) endif if (lnd_present) then call seq_io_write(rest_file,cdata_lx,fractions_lx,'fractions_lx',whead=whead,wdata=wdata) call seq_io_write(rest_file,cdata_lx,l2x_lx,'l2x_lx',whead=whead,wdata=wdata) endif if (ocn_present) then call seq_io_write(rest_file,cdata_ox,fractions_ox,'fractions_ox',whead=whead,wdata=wdata) call seq_io_write(rest_file,cdata_ox,o2x_ox,'o2x_ox',whead=whead,wdata=wdata) call seq_io_write(rest_file,cdata_ox,x2oacc_ox%data,'x2oacc_ox',whead=whead,wdata=wdata) ! call seq_io_write(rest_file,cdata_ox,x2oacc_ox%steps_done,'x2oacc_ox_cnt',whead=whead,wdata=wdata) call seq_io_write(rest_file,cdata_ox,x2oacc_ox_cnt,'x2oacc_ox_cnt',whead=whead,wdata=wdata) call seq_io_write(rest_file,cdata_ox,xao_ox,'xao_ox',whead=whead,wdata=wdata) call seq_io_write(rest_file,cdata_ax,xao_ax,'xao_ax',whead=whead,wdata=wdata) endif if (ice_present) then call seq_io_write(rest_file,cdata_ix,fractions_ix,'fractions_ix',whead=whead,wdata=wdata) call seq_io_write(rest_file,cdata_ix,i2x_ix,'i2x_ix',whead=whead,wdata=wdata) endif if (rof_present .and. ocnrof_prognostic) then call seq_io_write(rest_file,cdata_rx,r2xacc_rx%data,'r2xacc_rx',whead=whead,wdata=wdata) call seq_io_write(rest_file,cdata_rx,r2xacc_rx_cnt,'r2xacc_rx_cnt',whead=whead,wdata=wdata) endif if (glc_present) then call seq_io_write(rest_file,cdata_gx,fractions_gx,'fractions_gx',whead=whead,wdata=wdata) endif if (sno_present) then call seq_io_write(rest_file,cdata_sx,x2s_sx,'x2s_sx',whead=whead,wdata=wdata) endif enddo call seq_io_close(rest_file,cdata_ax) #if (defined NEW_BUDGET) deallocate(ds,ns) #endif if (drv_threading) call seq_comm_setnthreads(nthreads_GLOID) endif end subroutine seq_rest_write !=============================================================================== end module seq_rest_mod