Line data Source code
1 : module cam_restart
2 :
3 : ! Coordinate reading and writing of restart files.
4 :
5 : use shr_kind_mod, only: cl=>shr_kind_cl
6 : use spmd_utils, only: masterproc
7 : use cam_control_mod, only: restart_run, caseid
8 : use ioFileMod, only: opnfil
9 : use camsrfexch, only: cam_in_t, cam_out_t
10 : use dyn_comp, only: dyn_import_t, dyn_export_t
11 : use physics_buffer, only: physics_buffer_desc
12 : use units, only: getunit, freeunit
13 : use pio, only: file_desc_t, pio_global, pio_enddef, &
14 : pio_put_att, pio_closefile
15 :
16 : use cam_logfile, only: iulog
17 : use cam_abortutils, only: endrun
18 : use ionosphere_interface, only: ionosphere_init_restart, ionosphere_write_restart, ionosphere_read_restart
19 :
20 : implicit none
21 : private
22 : save
23 :
24 : public :: &
25 : cam_write_restart, & ! Driver for writing restart files
26 : cam_read_restart ! Driver for reading restart files
27 :
28 : !=========================================================================================
29 : contains
30 : !=========================================================================================
31 :
32 2304 : subroutine cam_read_restart(cam_in, cam_out, dyn_in, dyn_out, pbuf2d, &
33 : stop_ymd, stop_tod)
34 :
35 : use cam_initfiles, only: initial_file_get_id
36 : use restart_dynamics, only: read_restart_dynamics
37 : use restart_physics, only: read_restart_physics
38 : use camsrfexch, only: atm2hub_alloc, hub2atm_alloc
39 : use cam_history, only: read_restart_history
40 : use cam_pio_utils, only: clean_iodesc_list
41 :
42 : ! Arguments
43 : type(cam_in_t), pointer :: cam_in(:)
44 : type(cam_out_t), pointer :: cam_out(:)
45 : type(dyn_import_t), intent(inout) :: dyn_in
46 : type(dyn_export_t), intent(inout) :: dyn_out
47 : type(physics_buffer_desc), pointer :: pbuf2d(:,:)
48 : integer, intent(in) :: stop_ymd ! Stop date (YYYYMMDD)
49 : integer, intent(in) :: stop_tod ! Stop time of day (sec)
50 :
51 : ! Local workspace
52 : type(file_desc_t), pointer :: fh_ini
53 :
54 : character(len=*), parameter :: sub = 'cam_read_restart'
55 : !---------------------------------------------------------------------------
56 :
57 : ! get filehandle pointer to primary restart file
58 768 : fh_ini => initial_file_get_id()
59 :
60 768 : call read_restart_dynamics(fh_ini, dyn_in, dyn_out)
61 768 : call ionosphere_read_restart(fh_ini)
62 :
63 768 : call hub2atm_alloc(cam_in)
64 768 : call atm2hub_alloc(cam_out)
65 :
66 768 : call read_restart_physics(fh_ini, cam_in, cam_out, pbuf2d)
67 :
68 768 : if (restart_run) then
69 768 : call read_restart_history (fh_ini)
70 : end if
71 :
72 768 : call clean_iodesc_list()
73 :
74 768 : end subroutine cam_read_restart
75 :
76 : !=========================================================================================
77 :
78 1536 : subroutine cam_write_restart(cam_in, cam_out, dyn_out, pbuf2d, &
79 : yr_spec, mon_spec, day_spec, sec_spec )
80 :
81 768 : use filenames, only: interpret_filename_spec
82 : use cam_pio_utils, only: cam_pio_createfile, cam_pio_set_fill
83 : use restart_dynamics, only: write_restart_dynamics, init_restart_dynamics
84 : use restart_physics, only: write_restart_physics, init_restart_physics
85 : use cam_history, only: write_restart_history, init_restart_history
86 : use cam_instance, only: inst_suffix
87 :
88 : ! Arguments
89 : type(cam_in_t), intent(in) :: cam_in(:)
90 : type(cam_out_t), intent(in) :: cam_out(:)
91 : type(dyn_export_t), intent(in) :: dyn_out
92 : type(physics_buffer_desc), pointer :: pbuf2d(:,:)
93 : integer, optional, intent(in) :: yr_spec ! Simulation year
94 : integer, optional, intent(in) :: mon_spec ! Simulation month
95 : integer, optional, intent(in) :: day_spec ! Simulation day
96 : integer, optional, intent(in) :: sec_spec ! Seconds into current simulation day
97 :
98 : ! Local workspace
99 : character(len=cl) :: rfilename_spec ! filename specifier for primary restart file
100 : character(len=cl) :: fname ! Restart filename
101 : type(file_desc_t) :: fh
102 : integer :: ierr
103 : !-----------------------------------------------------------------------
104 :
105 : ! Set template for primary restart filename based on instance suffix
106 : ! (%c = caseid, $y = year, $m = month, $d = day, $s = seconds in day, %t = number)
107 1536 : rfilename_spec = '%c.cam' // trim(inst_suffix) //'.r.%y-%m-%d-%s.nc'
108 :
109 1536 : if (present(yr_spec).and.present(mon_spec).and.present(day_spec).and.present(sec_spec)) then
110 : fname = interpret_filename_spec( rfilename_spec, &
111 1536 : yr_spec=yr_spec, mon_spec=mon_spec, day_spec=day_spec, sec_spec= sec_spec )
112 : else
113 0 : fname = interpret_filename_spec( rfilename_spec )
114 : end if
115 :
116 1536 : call cam_pio_createfile(fh, trim(fname), 0)
117 1536 : ierr = cam_pio_set_fill(fh)
118 1536 : call init_restart_dynamics(fh, dyn_out)
119 1536 : call ionosphere_init_restart(fh)
120 1536 : call init_restart_physics(fh, pbuf2d)
121 1536 : call init_restart_history(fh)
122 :
123 1536 : ierr = pio_put_att(fh, pio_global, 'caseid', caseid)
124 :
125 1536 : ierr = pio_enddef(fh)
126 :
127 : !-----------------------------------------------------------------------
128 : ! Dynamics, physics, History
129 : !-----------------------------------------------------------------------
130 :
131 1536 : call write_restart_dynamics(fh, dyn_out)
132 1536 : call ionosphere_write_restart(fh)
133 1536 : call write_restart_physics(fh, cam_in, cam_out, pbuf2d)
134 :
135 : if (present(yr_spec).and.present(mon_spec).and.&
136 1536 : present(day_spec).and.present(sec_spec)) then
137 : call write_restart_history(fh, yr_spec=yr_spec, mon_spec=mon_spec, &
138 1536 : day_spec=day_spec, sec_spec= sec_spec )
139 : else
140 0 : call write_restart_history(fh)
141 : end if
142 :
143 : ! Close the primary restart file
144 1536 : call pio_closefile(fh)
145 :
146 : ! Update the restart pointer file
147 1536 : call write_rest_pfile(fname)
148 :
149 3072 : end subroutine cam_write_restart
150 :
151 : !========================================================================================
152 :
153 1536 : subroutine write_rest_pfile(restart_file)
154 :
155 : ! Write the restart pointer file
156 :
157 1536 : use cam_initfiles, only: rest_pfile
158 :
159 : character(len=*), intent(in) :: restart_file
160 :
161 : integer :: nsds, ierr
162 : character(len=*), parameter :: sub='write_rest_pfile'
163 : !---------------------------------------------------------------------------
164 :
165 1536 : if (masterproc) then
166 :
167 2 : nsds = getunit()
168 2 : call opnfil(rest_pfile, nsds, 'f')
169 2 : rewind nsds
170 2 : write(nsds, '(a)', iostat=ierr) trim(restart_file)
171 2 : if (ierr /= 0) then
172 0 : call endrun(sub//': ERROR: writing rpointer file')
173 : end if
174 2 : close(nsds)
175 2 : call freeunit(nsds)
176 :
177 2 : write(iulog,*)'(WRITE_REST_PFILE): successfully wrote local restart pointer file ',&
178 4 : trim(rest_pfile)
179 2 : write(iulog,'("---------------------------------------")')
180 : end if
181 :
182 1536 : end subroutine write_rest_pfile
183 :
184 : !========================================================================================
185 :
186 : end module cam_restart
|