MONC
writecheckpoint.F90
Go to the documentation of this file.
1 
3 #ifndef TEST_MODE
4  use netcdf, only : nf90_double, nf90_real, nf90_int, nf90_char, nf90_global, nf90_clobber, nf90_netcdf4, nf90_mpiio, &
5  nf90_collective, nf90_def_var, nf90_var_par_access, nf90_def_var_fill, nf90_put_att, nf90_create, nf90_put_var, &
6  nf90_def_dim, nf90_enddef, nf90_close, nf90_inq_dimid, nf90_inq_varid
7 #else
10 #endif
11  use state_mod, only : model_state_type
24  use mpi, only : mpi_info_null
25  implicit none
26 
27 #ifndef TEST_MODE
28  private
29 #endif
30 
31  character(len=*), parameter :: checkpoint_title = "MONC checkpoint file"
32 
34 
35 contains
36 
40  subroutine write_checkpoint_file(current_state, filename)
41  type(model_state_type), intent(inout) :: current_state
42  character(len=*), intent(in) :: filename
43 
44  integer :: ncid, z_dim_id, y_dim_id, x_dim_id, q_dim_id, x_id, y_id, z_id, th_id, p_id, time_id,&
45  u_id, v_id, w_id, q_id, zu_id, zv_id, zw_id, zth_id, zq_id, timestep_id, ugal_id, &
46  vgal_id, number_q_fields_id, string_dim_id, key_value_dim_id, options_id, q_indices_id, &
47  dtm_id, dtm_new_id, absolute_new_dtm_id
48  logical :: q_indices_declared
49 
50 #ifdef SINGLE_MONC_DO_SEQUENTIAL_NETCDF
51  if (current_state%parallel%processes .gt. 1) then
52  call check_status(nf90_create(filename, ior(nf90_netcdf4, nf90_mpiio), ncid, &
53  comm = current_state%parallel%monc_communicator, info = mpi_info_null))
54  else
55  call check_status(nf90_create(filename, nf90_clobber, ncid))
56  end if
57 #else
58  call check_status(nf90_create(filename, ior(nf90_netcdf4, nf90_mpiio), ncid, &
59  comm = current_state%parallel%monc_communicator, info = mpi_info_null))
60 #endif
62  call define_grid_dimensions(current_state, ncid, z_dim_id, y_dim_id, x_dim_id)
63  if (current_state%number_q_fields .gt. 0) call define_q_field_dimension(current_state, ncid, q_dim_id)
64 
65  call define_options_variable(current_state, ncid, string_dim_id, key_value_dim_id, options_id)
66  q_indices_declared=define_q_indices_variable(ncid, string_dim_id, key_value_dim_id, q_indices_id)
67  call define_grid_variables(current_state, ncid)
68  call define_mean_fields(current_state, ncid)
69  if (current_state%number_q_fields .gt. 0) call define_q_variable(ncid, current_state%parallel%processes .gt. 1, &
70  q_dim_id, z_dim_id, y_dim_id, x_dim_id, q_id, zq_id)
71  call define_prognostic_variables(current_state, current_state%parallel%processes .gt. 1, ncid, z_dim_id, y_dim_id, &
72  x_dim_id, u_id, v_id, w_id, th_id, p_id, zu_id, zv_id, zw_id, zth_id)
73  call define_misc_variables(ncid, timestep_id, time_id, ugal_id, vgal_id, number_q_fields_id, &
74  dtm_id, dtm_new_id, absolute_new_dtm_id)
75 
76  call check_status(nf90_enddef(ncid))
77 
78  if (current_state%parallel%my_rank==0) call write_out_grid(ncid, current_state%global_grid)
79  if (current_state%parallel%my_rank==0) call write_out_mean_fields(ncid, current_state%global_grid)
80  call write_out_all_fields(current_state, ncid, u_id, v_id, w_id, zu_id, zv_id, zw_id, th_id, zth_id, q_id, zq_id, p_id)
81  if (current_state%parallel%my_rank==0) then
82  call write_out_options(current_state, ncid, options_id)
83  if (q_indices_declared) call write_out_q_indices(ncid, q_indices_id)
84  call write_out_misc_variables(current_state, ncid, timestep_id, time_id, &
85  ugal_id, vgal_id, number_q_fields_id, dtm_id, dtm_new_id, absolute_new_dtm_id)
86  end if
87 
88  call check_status(nf90_close(ncid))
89  end subroutine write_checkpoint_file
90 
93  subroutine write_out_global_attributes(ncid)
94  integer, intent(in) :: ncid
95 
96  integer :: date_values(8)
97 
98  call date_and_time(values=date_values)
99 
101  call check_status(nf90_put_att(ncid, nf90_global, created_attribute_key, trim(conv_to_string(date_values(3)))//"/"//&
102  trim(conv_to_string(date_values(2)))//"/"//trim(conv_to_string(date_values(1)))//" "//trim(conv_to_string(&
103  date_values(5)))// ":"//trim(conv_to_string(date_values(6)))//":"//trim(conv_to_string(date_values(7)))))
104  end subroutine write_out_global_attributes
105 
109  subroutine write_out_q_indices(ncid, q_indices_id)
110  integer, intent(in) :: ncid, q_indices_id
111 
112  integer :: i, current_index
113  type(q_metadata_type) :: specific_q_data
114 
115  current_index=1
116  do i=1, get_max_number_q_indices()
117  specific_q_data=get_indices_descriptor(i)
118  if (specific_q_data%l_used) then
119  call check_status(nf90_put_var(ncid, q_indices_id, trim(specific_q_data%name), (/ 1, 1, current_index /)))
120  call check_status(nf90_put_var(ncid, q_indices_id, trim(conv_to_string(i)), (/ 1, 2, current_index /)))
121  current_index=current_index+1
122  end if
123  end do
124  end subroutine write_out_q_indices
125 
130  subroutine write_out_options(current_state, ncid, options_id)
131  type(model_state_type), intent(inout) :: current_state
132  integer, intent(in) :: ncid, options_id
133 
134  integer :: i
135  character(len=STRING_LENGTH), pointer :: sized_raw_character
136  class(*), pointer :: raw_data, raw_to_string
137 
138  do i=1,options_size(current_state%options_database)
139  raw_data=> options_value_at(current_state%options_database, i)
140  raw_to_string=>raw_data
141  call check_status(nf90_put_var(ncid, options_id, trim(options_key_at(current_state%options_database, i)), (/ 1, 1, i /)))
142  select type (raw_data)
143  type is(integer)
144  call check_status(nf90_put_var(ncid, options_id, trim(conv_to_string(raw_data)), (/ 1, 2, i /)))
145  type is(real(kind=single_precision))
146  call check_status(nf90_put_var(ncid, options_id, trim(conv_to_string(raw_data)), (/ 1, 2, i /)))
147  type is(real(kind=double_precision))
148  call check_status(nf90_put_var(ncid, options_id, trim(conv_to_string(raw_data)), (/ 1, 2, i /)))
149  type is(logical)
150  call check_status(nf90_put_var(ncid, options_id, trim(conv_to_string(raw_data)), (/ 1, 2, i /)))
151  type is(character(len=*))
152  ! Done this way to give the character size information and keep the (unsafe) cast in the conversion module
153  sized_raw_character=>conv_to_string(raw_to_string, .false., string_length)
154  call check_status(nf90_put_var(ncid, options_id, trim(sized_raw_character), (/ 1, 2, i /)))
155  end select
156  end do
157  end subroutine write_out_options
158 
165  subroutine write_out_all_fields(current_state, ncid, u_id, v_id, w_id, zu_id, zv_id, zw_id, th_id, zth_id, q_id, zq_id, p_id)
166  type(model_state_type), intent(inout) :: current_state
167  integer, intent(in) :: ncid, u_id, v_id, w_id, zu_id, zv_id, zw_id, th_id, zth_id, q_id, zq_id, p_id
168 
169  integer :: i
170  logical :: multi_process
171 
172  multi_process = current_state%parallel%processes .gt. 1
173 #ifdef U_ACTIVE
174  call write_out_velocity_field(ncid, current_state%local_grid, current_state%u, u_id, multi_process)
175  call write_out_velocity_field(ncid, current_state%local_grid, current_state%zu, zu_id, multi_process)
176 #endif
177 #ifdef V_ACTIVE
178  call write_out_velocity_field(ncid, current_state%local_grid, current_state%v, v_id, multi_process)
179  call write_out_velocity_field(ncid, current_state%local_grid, current_state%zv, zv_id, multi_process)
180 #endif
181 #ifdef W_ACTIVE
182  call write_out_velocity_field(ncid, current_state%local_grid, current_state%w, w_id, multi_process)
183  call write_out_velocity_field(ncid, current_state%local_grid, current_state%zw, zw_id, multi_process)
184 #endif
185  if (current_state%th%active) then
186  call write_out_velocity_field(ncid, current_state%local_grid, current_state%th, th_id, multi_process)
187  call write_out_velocity_field(ncid, current_state%local_grid, current_state%zth, zth_id, multi_process)
188  end if
189  if (current_state%p%active) call write_out_velocity_field(ncid, current_state%local_grid, current_state%p, &
190  p_id, multi_process)
191  do i=1,current_state%number_q_fields
192  if (current_state%q(i)%active) then
193  call write_out_velocity_field(ncid, current_state%local_grid, current_state%q(i), q_id, multi_process, i)
194  call write_out_velocity_field(ncid, current_state%local_grid, current_state%zq(i), zq_id, multi_process, i)
195  end if
196  end do
197  end subroutine write_out_all_fields
198 
204  subroutine write_out_velocity_field(ncid, local_grid, field, variable_id, multi_process, fourth_dim_loc)
205  integer, intent(in) :: ncid, variable_id
206  type(prognostic_field_type), intent(in) :: field
207  type(local_grid_type), intent(inout) :: local_grid
208  logical, intent(in) :: multi_process
209  integer, optional, intent(in) :: fourth_dim_loc
210 
211  integer :: start(4), count(4), i, map(4)
212 
213  if (multi_process .or. present(fourth_dim_loc)) then
214  do i=1,3
215  if (i==1) then
216  map(i)=1
217  else
218  map(i)=map(i-1)*local_grid%size(i-1)
219  end if
220  start(i) = local_grid%start(i)
221  count(i) = local_grid%size(i)
222  end do
223  if (present(fourth_dim_loc)) then
224  start(4) = fourth_dim_loc
225  count(4) = 1
226  map(4)=map(3)*local_grid%size(3)
227  end if
228 
229  call check_status(nf90_put_var(ncid, variable_id, field%data(local_grid%local_domain_start_index(z_index):&
230  local_grid%local_domain_end_index(z_index),local_grid%local_domain_start_index(y_index):&
231  local_grid%local_domain_end_index(y_index), local_grid%local_domain_start_index(x_index):&
232  local_grid%local_domain_end_index(x_index)), start=start, count=count))
233  else
234  call check_status(nf90_put_var(ncid, variable_id, field%data(local_grid%local_domain_start_index(z_index):&
235  local_grid%local_domain_end_index(z_index),local_grid%local_domain_start_index(y_index):&
236  local_grid%local_domain_end_index(y_index), local_grid%local_domain_start_index(x_index):&
237  local_grid%local_domain_end_index(x_index))))
238  end if
239  end subroutine write_out_velocity_field
240 
247  subroutine write_out_grid(ncid, grid)
248  integer, intent(in) :: ncid
249  type(global_grid_type), intent(in) :: grid
250 
251  integer :: var_id
252 
253  if (grid%active(z_index)) then
254  call write_z_grid_gimension(ncid, grid%configuration%vertical)
255  end if
256  if (grid%active(y_index)) then
257  call check_status(nf90_inq_varid(ncid, y_resolution, var_id))
258  call check_status(nf90_put_var(ncid, var_id, grid%resolution(y_index)))
259  call check_status(nf90_inq_varid(ncid, y_top, var_id))
260  call check_status(nf90_put_var(ncid, var_id, grid%top(y_index)))
261  call check_status(nf90_inq_varid(ncid, y_bottom, var_id))
262  call check_status(nf90_put_var(ncid, var_id, grid%bottom(y_index)))
263  end if
264  if (grid%active(x_index)) then
265  call check_status(nf90_inq_varid(ncid, x_resolution, var_id))
266  call check_status(nf90_put_var(ncid, var_id, grid%resolution(x_index)))
267  call check_status(nf90_inq_varid(ncid, x_top, var_id))
268  call check_status(nf90_put_var(ncid, var_id, grid%top(x_index)))
269  call check_status(nf90_inq_varid(ncid, x_bottom, var_id))
270  call check_status(nf90_put_var(ncid, var_id, grid%bottom(x_index)))
271  end if
272  end subroutine write_out_grid
273 
274  subroutine write_out_mean_fields(ncid, grid)
275  integer, intent(in) :: ncid
276  type(global_grid_type), intent(in) :: grid
277 
278  integer :: var_id
279 
280  if (allocated(grid%configuration%vertical%olubar)) then
281  call check_status(nf90_inq_varid(ncid, olubar, var_id))
282  call check_status(nf90_put_var(ncid, var_id, grid%configuration%vertical%olubar))
283  end if
284  if (allocated(grid%configuration%vertical%olzubar)) then
285  call check_status(nf90_inq_varid(ncid, olzubar, var_id))
286  call check_status(nf90_put_var(ncid, var_id, grid%configuration%vertical%olzubar))
287  end if
288  if (allocated(grid%configuration%vertical%olvbar)) then
289  call check_status(nf90_inq_varid(ncid, olvbar, var_id))
290  call check_status(nf90_put_var(ncid, var_id, grid%configuration%vertical%olvbar))
291  end if
292  if (allocated(grid%configuration%vertical%olzvbar)) then
293  call check_status(nf90_inq_varid(ncid, olzvbar, var_id))
294  call check_status(nf90_put_var(ncid, var_id, grid%configuration%vertical%olzvbar))
295  end if
296  if (allocated(grid%configuration%vertical%olthbar)) then
297  call check_status(nf90_inq_varid(ncid, olthbar, var_id))
298  call check_status(nf90_put_var(ncid, var_id, grid%configuration%vertical%olthbar))
299  end if
300  if (allocated(grid%configuration%vertical%olzthbar)) then
301  call check_status(nf90_inq_varid(ncid, olzthbar, var_id))
302  call check_status(nf90_put_var(ncid, var_id, grid%configuration%vertical%olzthbar))
303  end if
304  if (allocated(grid%configuration%vertical%olqbar)) then
305  call check_status(nf90_inq_varid(ncid, olqbar, var_id))
306  call check_status(nf90_put_var(ncid, var_id, grid%configuration%vertical%olqbar))
307  end if
308  if (allocated(grid%configuration%vertical%olzqbar)) then
309  call check_status(nf90_inq_varid(ncid, olzqbar, var_id))
310  call check_status(nf90_put_var(ncid, var_id, grid%configuration%vertical%olzqbar))
311  end if
312  end subroutine write_out_mean_fields
313 
318  subroutine write_z_grid_gimension(ncid, vertical_grid)
319  type(vertical_grid_configuration_type), intent(in) :: vertical_grid
320  integer, intent(in) :: ncid
321 
322  integer :: z_var_id, zn_var_id, thref_var_id
323 
324  call check_status(nf90_inq_varid(ncid, z_key, z_var_id))
325  call check_status(nf90_put_var(ncid, z_var_id, vertical_grid%z))
326  call check_status(nf90_inq_varid(ncid, zn_key, zn_var_id))
327  call check_status(nf90_put_var(ncid, zn_var_id, vertical_grid%zn))
328  call check_status(nf90_inq_varid(ncid, thref, thref_var_id))
329  call check_status(nf90_put_var(ncid, thref_var_id, vertical_grid%thref))
330  end subroutine write_z_grid_gimension
331 
337  subroutine define_options_variable(current_state, ncid, string_dim_id, key_value_dim_id, options_id)
338  type(model_state_type), intent(inout) :: current_state
339  integer, intent(in) :: ncid
340  integer, intent(out) :: string_dim_id, key_value_dim_id, options_id
341 
342  integer :: options_dim_id, command_dimensions(3)
343 
344  call check_status(nf90_def_dim(ncid, string_dim_key, string_length, string_dim_id))
345  call check_status(nf90_def_dim(ncid, key_value_pair_key, 2, key_value_dim_id))
346  call check_status(nf90_def_dim(ncid, options_dim_key, options_size(current_state%options_database), options_dim_id))
347 
348  command_dimensions = (/ string_dim_id, key_value_dim_id, options_dim_id /)
349 
350  call check_status(nf90_def_var(ncid, options_key, nf90_char, command_dimensions, options_id))
351  end subroutine define_options_variable
352 
360  logical function define_q_indices_variable(ncid, string_dim_id, key_value_dim_id, q_indices_id)
361  integer, intent(in) :: ncid, string_dim_id, key_value_dim_id
362  integer, intent(out) :: q_indices_id
363 
364  integer :: q_indices_dim_id, command_dimensions(3), number_active_q
365 
366  number_active_q=get_number_active_q_indices()
367 
368  if (number_active_q == 0) then
370  else
371  call check_status(nf90_def_dim(ncid, q_indices_dim_key, number_active_q, q_indices_dim_id))
372 
373  command_dimensions = (/ string_dim_id, key_value_dim_id, q_indices_dim_id /)
374 
375  call check_status(nf90_def_var(ncid, q_indices_key, nf90_char, command_dimensions, q_indices_id))
377  end if
378  end function define_q_indices_variable
379 
384  subroutine define_q_field_dimension(current_state, ncid, q_dim_id)
385  type(model_state_type), intent(inout) :: current_state
386  integer, intent(in) :: ncid
387  integer, intent(out) :: q_dim_id
388 
389  call check_status(nf90_def_dim(ncid, q_dim_key, current_state%number_q_fields, q_dim_id))
390  end subroutine define_q_field_dimension
391 
398  subroutine define_grid_dimensions(current_state, ncid, z_dim_id, y_dim_id, x_dim_id)
399  type(model_state_type), intent(inout) :: current_state
400  integer, intent(in) :: ncid
401  integer, intent(out) :: z_dim_id, y_dim_id, x_dim_id
402 
403  integer :: empty_dim_id
404 
405  call check_status(nf90_def_dim(ncid, empty_dim_key, 1, empty_dim_id))
406 
407  if (current_state%global_grid%active(z_index)) then
408  call check_status(nf90_def_dim(ncid, z_dim_key, current_state%global_grid%size(z_index), z_dim_id))
409  call check_status(nf90_def_dim(ncid, zn_dim_key, current_state%global_grid%size(z_index), z_dim_id))
410  else
411  z_dim_id = empty_dim_id
412  end if
413  if (current_state%global_grid%active(y_index)) then
414  call check_status(nf90_def_dim(ncid, y_dim_key, current_state%global_grid%size(y_index), y_dim_id))
415  else
416  y_dim_id = empty_dim_id
417  end if
418  if (current_state%global_grid%active(x_index)) then
419  call check_status(nf90_def_dim(ncid, x_dim_key, current_state%global_grid%size(x_index), x_dim_id))
420  else
421  x_dim_id = empty_dim_id
422  end if
423  end subroutine define_grid_dimensions
424 
434  subroutine define_grid_variables(current_state, ncid)
435  type(model_state_type), intent(inout) :: current_state
436  integer, intent(in) :: ncid
437 
438  integer :: var_id, z_dim_id
439 
440  if (current_state%global_grid%active(x_index)) then
441  call check_status(nf90_def_var(ncid, x_resolution, nf90_double, var_id))
442  call check_status(nf90_put_att(ncid, var_id, "units", "m"))
443  call check_status(nf90_def_var(ncid, x_top, nf90_double, var_id))
444  call check_status(nf90_put_att(ncid, var_id, "units", "m"))
445  call check_status(nf90_def_var(ncid, x_bottom, nf90_double, var_id))
446  call check_status(nf90_put_att(ncid, var_id, "units", "m"))
447  end if
448  if (current_state%global_grid%active(y_index)) then
449  call check_status(nf90_def_var(ncid, y_resolution, nf90_double, var_id))
450  call check_status(nf90_put_att(ncid, var_id, "units", "m"))
451  call check_status(nf90_def_var(ncid, y_top, nf90_double, var_id))
452  call check_status(nf90_put_att(ncid, var_id, "units", "m"))
453  call check_status(nf90_def_var(ncid, y_bottom, nf90_double, var_id))
454  call check_status(nf90_put_att(ncid, var_id, "units", "m"))
455  end if
456  if (current_state%global_grid%active(z_index)) then
457  call check_status(nf90_inq_dimid(ncid, z_dim_key, z_dim_id))
458  call check_status(nf90_def_var(ncid, z_key, nf90_double, z_dim_id, var_id))
459  call check_status(nf90_put_att(ncid, var_id, "units", "m"))
460  call check_status(nf90_inq_dimid(ncid, zn_dim_key, z_dim_id))
461  call check_status(nf90_def_var(ncid, zn_key, nf90_double, z_dim_id, var_id))
462  call check_status(nf90_put_att(ncid, var_id, "units", "m"))
463  end if
464  call check_status(nf90_inq_dimid(ncid, z_dim_key, z_dim_id))
465  call check_status(nf90_def_var(ncid, thref, nf90_double, z_dim_id, var_id))
466  end subroutine define_grid_variables
467 
468  subroutine define_mean_fields(current_state, ncid)
469  type(model_state_type), intent(inout) :: current_state
470  integer, intent(in) :: ncid
471 
472  integer :: var_id, z_dim_id, q_dim_id, qdimids(2)
473 
474  call check_status(nf90_inq_dimid(ncid, z_dim_key, z_dim_id))
475 
476  if (allocated(current_state%global_grid%configuration%vertical%olubar)) then
477  call check_status(nf90_def_var(ncid, olubar, nf90_double, z_dim_id, var_id))
478  end if
479  if (allocated(current_state%global_grid%configuration%vertical%olzubar)) then
480  call check_status(nf90_def_var(ncid, olzubar, nf90_double, z_dim_id, var_id))
481  end if
482  if (allocated(current_state%global_grid%configuration%vertical%olvbar)) then
483  call check_status(nf90_def_var(ncid, olvbar, nf90_double, z_dim_id, var_id))
484  end if
485  if (allocated(current_state%global_grid%configuration%vertical%olzvbar)) then
486  call check_status(nf90_def_var(ncid, olzvbar, nf90_double, z_dim_id, var_id))
487  end if
488  if (allocated(current_state%global_grid%configuration%vertical%olthbar)) then
489  call check_status(nf90_def_var(ncid, olthbar, nf90_double, z_dim_id, var_id))
490  end if
491  if (allocated(current_state%global_grid%configuration%vertical%olzthbar)) then
492  call check_status(nf90_def_var(ncid, olzthbar, nf90_double, z_dim_id, var_id))
493  end if
494  if (allocated(current_state%global_grid%configuration%vertical%olqbar) .or. &
495  allocated(current_state%global_grid%configuration%vertical%olzqbar)) then
496  call check_status(nf90_inq_dimid(ncid, q_dim_key, q_dim_id))
497  qdimids=(/ z_dim_id, q_dim_id /)
498  if (allocated(current_state%global_grid%configuration%vertical%olqbar)) then
499  call check_status(nf90_def_var(ncid, olqbar, nf90_double, qdimids, var_id))
500  end if
501  if (allocated(current_state%global_grid%configuration%vertical%olzqbar)) then
502  call check_status(nf90_def_var(ncid, olzqbar, nf90_double, qdimids, var_id))
503  end if
504  end if
505  end subroutine define_mean_fields
506 
516  subroutine define_q_variable(ncid, multi_process, q_dim_id, z_dim_id, y_dim_id, x_dim_id, q_id, zq_id)
517  logical, intent(in) :: multi_process
518  integer, intent(in) :: ncid, z_dim_id, y_dim_id, x_dim_id, q_dim_id
519  integer, intent(out) :: q_id, zq_id
520 
521  integer, dimension(:), allocatable :: dimids
522 
523  allocate(dimids(4))
524  dimids = (/ z_dim_id, y_dim_id, x_dim_id, q_dim_id /)
525 
526  call check_status(nf90_def_var(ncid, q_key, merge(nf90_double, nf90_real, &
527  default_precision == double_precision), dimids, q_id))
529  default_precision == double_precision), dimids, zq_id))
530 
531  if (multi_process) then
532  call check_status(nf90_def_var_fill(ncid, q_id, 1, 1))
533  call check_status(nf90_def_var_fill(ncid, zq_id, 1, 1))
534  call check_status(nf90_var_par_access(ncid, q_id, nf90_collective))
535  call check_status(nf90_var_par_access(ncid, zq_id, nf90_collective))
536  end if
537  end subroutine define_q_variable
538 
551  subroutine define_prognostic_variables(current_state, multi_process, ncid, z_dim_id, &
552  y_dim_id, x_dim_id, u_id, v_id, w_id, th_id, p_id, zu_id, zv_id, zw_id, zth_id)
553  type(model_state_type), intent(inout) :: current_state
554  logical, intent(in) :: multi_process
555  integer, intent(in) :: ncid, z_dim_id, y_dim_id, x_dim_id
556  integer, intent(out) :: u_id, v_id, w_id, th_id, p_id, zu_id, zv_id, zw_id, zth_id
557 
558 #ifdef U_ACTIVE
559  call define_velocity_variable(ncid, multi_process, z_dim_id, y_dim_id, x_dim_id, field_name=u_key, field_id=u_id)
560  call define_velocity_variable(ncid, multi_process, z_dim_id, y_dim_id, x_dim_id, field_name=zu_key, field_id=zu_id)
561 #endif
562 #ifdef V_ACTIVE
563  call define_velocity_variable(ncid, multi_process, z_dim_id, y_dim_id, x_dim_id, field_name=v_key, field_id=v_id)
564  call define_velocity_variable(ncid, multi_process, z_dim_id, y_dim_id, x_dim_id, field_name=zv_key, field_id=zv_id)
565 #endif
566 #ifdef W_ACTIVE
567  call define_velocity_variable(ncid, multi_process, z_dim_id, y_dim_id, x_dim_id, field_name=w_key, field_id=w_id)
568  call define_velocity_variable(ncid, multi_process, z_dim_id, y_dim_id, x_dim_id, field_name=zw_key, field_id=zw_id)
569 #endif
570  if (current_state%th%active) then
571  call define_velocity_variable(ncid, multi_process, z_dim_id, y_dim_id, x_dim_id, field_name=th_key, field_id=th_id)
572  call define_velocity_variable(ncid, multi_process, z_dim_id, y_dim_id, x_dim_id, field_name=zth_key, field_id=zth_id)
573  end if
574  if (current_state%p%active) then
575  call define_velocity_variable(ncid, multi_process, z_dim_id, y_dim_id, x_dim_id, field_name=p_key, field_id=p_id)
576  end if
577  end subroutine define_prognostic_variables
578 
582  subroutine define_misc_variables(ncid, timestep_id, time_id, ugal_id, vgal_id, number_q_fields_id, &
583  dtm_id, dtm_new_id, absolute_new_dtm_id)
584  integer, intent(in) :: ncid
585  integer, intent(out) :: timestep_id, time_id, ugal_id, vgal_id, number_q_fields_id, dtm_id, dtm_new_id, absolute_new_dtm_id
586 
587  call check_status(nf90_def_var(ncid, timestep, nf90_int, timestep_id))
588  call check_status(nf90_def_var(ncid, time_key, nf90_double, time_id))
589  call check_status(nf90_def_var(ncid, ugal, nf90_double, ugal_id))
590  call check_status(nf90_def_var(ncid, vgal, nf90_double, vgal_id))
591  call check_status(nf90_def_var(ncid, nqfields, nf90_int, number_q_fields_id))
592  call check_status(nf90_def_var(ncid, dtm_key, nf90_double, dtm_id))
593  call check_status(nf90_def_var(ncid, dtm_new_key, nf90_double, dtm_new_id))
594  call check_status(nf90_def_var(ncid, absolute_new_dtm_key, nf90_double, absolute_new_dtm_id))
595  end subroutine define_misc_variables
596 
601  subroutine write_out_misc_variables(current_state, ncid, timestep_id, time_id, ugal_id, &
602  vgal_id, number_q_fields_id, dtm_id, dtm_new_id, absolute_new_dtm_id)
603  type(model_state_type), intent(inout) :: current_state
604  integer, intent(in) :: ncid, timestep_id, time_id, ugal_id, vgal_id, number_q_fields_id, &
605  dtm_id, dtm_new_id, absolute_new_dtm_id
606 
607  call check_status(nf90_put_var(ncid, timestep_id, current_state%timestep))
608  ! The time is incremented with dtm as the model was about to increment for the next step and this is needed for diagnostics
609  call check_status(nf90_put_var(ncid, time_id, current_state%time+current_state%dtm))
610  call check_status(nf90_put_var(ncid, ugal_id, current_state%ugal))
611  call check_status(nf90_put_var(ncid, vgal_id, current_state%vgal))
612  call check_status(nf90_put_var(ncid, number_q_fields_id, current_state%number_q_fields))
613  call check_status(nf90_put_var(ncid, dtm_id, current_state%dtm))
614  call check_status(nf90_put_var(ncid, dtm_new_id, current_state%dtm_new))
615  call check_status(nf90_put_var(ncid, absolute_new_dtm_id, current_state%absolute_new_dtm))
616  end subroutine write_out_misc_variables
617 
625  subroutine define_velocity_variable(ncid, multi_process, dimone, dimtwo, dimthree, field_name, field_id)
626  integer, intent(in) :: ncid, dimone
627  integer, intent(in), optional :: dimtwo, dimthree
628  integer, intent(out) :: field_id
629  character(len=*), intent(in) :: field_name
630  logical, intent(in) :: multi_process
631 
632  integer, dimension(:), allocatable :: dimids
633 
634  if (present(dimtwo) .and. present(dimthree)) then
635  allocate(dimids(3))
636  dimids = (/ dimone, dimtwo, dimthree /)
637  else if (present(dimtwo) .or. present(dimthree)) then
638  allocate(dimids(2))
639  dimids = (/ dimone, merge(dimtwo, dimthree, present(dimtwo)) /)
640  else
641  allocate(dimids(1))
642  dimids = (/ dimone /)
643  end if
644 
646  dimids, field_id))
647  if (multi_process) then
648  call check_status(nf90_def_var_fill(ncid, field_id, 1, 1))
649  call check_status(nf90_var_par_access(ncid, field_id, nf90_collective))
650  end if
651  call check_status(nf90_put_att(ncid, field_id, "units", "m/s"))
652  end subroutine define_velocity_variable
character(len= *), parameter olubar
subroutine write_out_velocity_field(ncid, local_grid, field, variable_id, multi_process, fourth_dim_loc)
Will write out a single velocity field to the checkpoint file. If there are multiple processes then w...
character(len= *), parameter p_key
Pressure variable NetCDF key.
character(len= *), parameter zn_key
character(len= *), parameter olzthbar
character(len= *), parameter y_key
character(len= *), parameter u_key
U variable NetCDF key.
subroutine, public write_checkpoint_file(current_state, filename)
Will write out the current model state_mod into a NetCDF checkpoint file.
character(len= *), parameter key_value_pair_key
Key-value pair dimension key.
subroutine write_z_grid_gimension(ncid, vertical_grid)
Writes out the Z dimension of the grids_mod points which are explicitly calculated.
character(len= *), parameter thref
subroutine define_grid_variables(current_state, ncid)
Defines the NetCDF grid variables. This works for 1, 2 or 3D grids_mod.
integer, parameter nf90_int
integer, parameter nf90_double
character(len= *), parameter q_key
Q variable NetCDF key.
subroutine define_misc_variables(ncid, timestep_id, time_id, ugal_id, vgal_id, number_q_fields_id, dtm_id, dtm_new_id, absolute_new_dtm_id)
Defines misc variables in the NetCDF file.
character(len= *), parameter empty_dim_key
Empty dimension key.
integer, parameter nf90_real
character(len= *), parameter y_dim_key
Y dimension/variable key.
integer function, public get_max_number_q_indices()
Gets the maximum number of Q indicies.
Definition: q_indices.F90:81
subroutine write_out_q_indices(ncid, q_indices_id)
Writes out the specific Q indicies that are active and need writing.
Contains prognostic field definitions and functions.
Definition: prognostics.F90:2
character(len= *), parameter y_top
character(len= *), parameter zv_key
A prognostic field which is assumed to be 3D.
Definition: prognostics.F90:13
Common checkpoint functionality which is used by reader and writers to NetCDF checkpoints.
character(len= *), parameter created_attribute_key
integer, parameter, public default_precision
MPI communication type which we use for the prognostic and calculation data.
Definition: datadefn.F90:17
character(len= *), parameter zth_key
integer, parameter, public z_index
Grid index parameters.
Definition: grids.F90:14
integer, parameter nf90_global
character(len= *), parameter x_key
subroutine write_out_options(current_state, ncid, options_id)
Writes out the options that the model was run with.
integer, parameter max_string_length
Maximum string length (stored size)
character(len= *), parameter timestep
Timestep NetCDF key.
character(len= *), parameter time_key
subroutine define_q_variable(ncid, multi_process, q_dim_id, z_dim_id, y_dim_id, x_dim_id, q_id, zq_id)
Defines the Q variable in the checkpoint file.
character(len= *), parameter zu_key
character(len= *), parameter z_dim_key
Z dimension/variable key.
character(len= *), parameter options_dim_key
Options dimension key.
Contains common definitions for the data and datatypes used by MONC.
Definition: datadefn.F90:2
subroutine write_out_mean_fields(ncid, grid)
character(len= *), parameter olzvbar
character(len= *), parameter v_key
V variable NetCDF key.
The ModelState which represents the current state of a run.
Definition: state.F90:39
character(len=string_length) function, public options_key_at(options_database, i)
Returns the ith key in the options database.
subroutine define_mean_fields(current_state, ncid)
Conversion between common inbuilt FORTRAN data types.
Definition: conversions.F90:5
Converts data types to strings.
Definition: conversions.F90:36
character(len= *), parameter olvbar
subroutine write_out_all_fields(current_state, ncid, u_id, v_id, w_id, zu_id, zv_id, zw_id, th_id, zth_id, q_id, zq_id, p_id)
Will write out all prognostic model fields to the checkpoint. It will work in 1, 2 or 3D depending on...
integer, parameter, public single_precision
Single precision (32 bit) kind.
Definition: datadefn.F90:13
character(len= *), parameter absolute_new_dtm_key
subroutine write_out_grid(ncid, grid)
Will write out the grid to the checkpoint, it will work in 1, 2 or 3D depending on what is in the mod...
character(len= *), parameter q_indices_key
The configuration of the grid vertically.
Definition: grids.F90:28
integer function nf90_enddef(ncid)
type(q_metadata_type) function, public get_indices_descriptor(i)
Retrieves the indicies descriptor at a specific location.
Definition: q_indices.F90:100
character(len= *), parameter z_key
integer, parameter, public double_precision
Double precision (64 bit) kind.
Definition: datadefn.F90:14
logical function define_q_indices_variable(ncid, string_dim_id, key_value_dim_id, q_indices_id)
Defines the NetCDF Q indices variable which is, same as the options, stored as key-value pair of stri...
character(len= *), parameter x_bottom
Defines the global grid.
Definition: grids.F90:100
subroutine define_velocity_variable(ncid, multi_process, dimone, dimtwo, dimthree, field_name, field_id)
Will define a single velocity variable in the NetCDF file.
integer, parameter nf90_clobber
This manages the Q variables and specifically the mapping between names and the index that they are s...
Definition: q_indices.F90:2
integer function nf90_put_att(ncid, attribute, key, value)
character(len= *), parameter string_dim_key
String dimension key.
integer function, public get_number_active_q_indices()
Gets the number of active Q indicies (i.e. those allocated to specific uses)
Definition: q_indices.F90:87
character(len= *), parameter w_key
W variable NetCDF key.
character(len= *), parameter title_attribute_key
character(len= *), parameter dtm_key
subroutine check_status(status, found_flag)
Will check a NetCDF status and write to log_log error any decoded statuses. Can be used to decode whe...
Defined the local grid, i.e. the grid held on this process after decomposition.
Definition: grids.F90:111
Writes out model state_mod to a checkpoint NetCDF file.
character(len= *), parameter q_dim_key
integer function nf90_create(path, mode, ncid, comm, info)
character(len= *), parameter olzubar
integer function nf90_close(ncid)
character(len= *), parameter y_bottom
character(len= *), parameter dtm_new_key
subroutine write_out_global_attributes(ncid)
Writes out global attributes into the checkpoint.
integer, parameter, public string_length
Default length of strings.
Definition: datadefn.F90:10
character(len= *), parameter olzqbar
subroutine define_options_variable(current_state, ncid, string_dim_id, key_value_dim_id, options_id)
Defines the NetCDF options variable which is basically a 3D character array to form key-value pair st...
class(*) function, pointer, public options_value_at(options_database, i)
Returns the value at index in the database.
character(len= *), parameter zn_dim_key
integer function, public options_size(options_database)
Returns the number of entries in the options database.
character(len= *), parameter olthbar
Functionality to support the different types of grid and abstraction between global grids and local o...
Definition: grids.F90:5
integer function nf90_def_dim(ncid, key, length, dimension_id)
character(len= *), parameter x_resolution
integer, parameter nf90_netcdf4
Manages the options database. Contains administration functions and deduce runtime options from the c...
character(len= *), parameter q_indices_dim_key
character(len= *), parameter x_dim_key
X dimension/variable key.
integer, parameter nf90_mpiio
character(len= *), parameter th_key
Theta variable NetCDF key.
character(len= *), parameter olqbar
character(len= *), parameter zq_key
character(len= *), parameter vgal
character(len= *), parameter zw_key
subroutine define_prognostic_variables(current_state, multi_process, ncid, z_dim_id, y_dim_id, x_dim_id, u_id, v_id, w_id, th_id, p_id, zu_id, zv_id, zw_id, zth_id)
Defines prognostic variables in the NetCDF. This handles 1, 2 and 3D grids_mod and 1...
character(len= *), parameter ugal
integer, parameter nf90_char
character(len= *), parameter x_top
The model state which represents the current state of a run.
Definition: state.F90:2
subroutine define_grid_dimensions(current_state, ncid, z_dim_id, y_dim_id, x_dim_id)
Will define the grid dimensions and works for 1, 2 or 3D grids_mod.
integer, parameter, public y_index
Definition: grids.F90:14
character(len= *), parameter options_key
Options variable key.
character(len= *), parameter nqfields
subroutine define_q_field_dimension(current_state, ncid, q_dim_id)
Defines the Q field dimension in the NetCDF.
integer, parameter, public x_index
Definition: grids.F90:14
character(len= *), parameter y_resolution
subroutine write_out_misc_variables(current_state, ncid, timestep_id, time_id, ugal_id, vgal_id, number_q_fields_id, dtm_id, dtm_new_id, absolute_new_dtm_id)
Will dump out (write) misc model data to the checkpoint.
character(len= *), parameter checkpoint_title
Title of the NetCDF file.