31 use mom_cpu_clock, only : cpu_clock_id, cpu_clock_begin, cpu_clock_end
51 use diag_axis_mod
, only : get_diag_axis_name
52 use diag_manager_mod
, only : diag_manager_init, diag_manager_end
53 use diag_manager_mod
, only : send_data, diag_axis_init, diag_field_add_attribute
58 use diag_manager_mod
, only : get_diag_field_id_fms=>get_diag_field_id
59 use diag_manager_mod
, only : diag_field_not_found
61 implicit none ;
private 63 #define __DO_SAFETY_CHECKS__ 64 #define IMPLIES(A, B) ((.not. (A)) .or. (B)) 86 character(len=15) :: id
88 integer,
dimension(:),
allocatable :: handles
92 character(len=9) :: x_cell_method =
'' 93 character(len=9) :: y_cell_method =
'' 94 character(len=9) :: v_cell_method =
'' 97 integer :: vertical_coordinate_number = 0
99 logical :: is_h_point = .false.
100 logical :: is_q_point = .false.
101 logical :: is_u_point = .false.
102 logical :: is_v_point = .false.
103 logical :: is_layer = .false.
104 logical :: is_interface = .false.
105 logical :: is_native = .true.
107 logical :: needs_remapping = .false.
109 logical :: needs_interpolating = .false.
114 integer :: id_area = -1
115 integer :: id_volume = -1
126 integer :: fms_diag_id
127 integer :: fms_xyave_diag_id = -1
128 character(32) :: debug_str =
'' 130 real,
pointer,
dimension(:,:) :: mask2d => null()
131 real,
pointer,
dimension(:,:,:) :: mask3d => null()
133 real :: conversion_factor = 0.
134 logical :: v_extensive = .false.
140 integer :: doc_unit = -1
144 integer :: is, ie, js, je
145 integer :: isd, ied, jsd, jed
148 type(time_type) :: time_end
150 logical :: ave_enabled = .false.
159 real,
dimension(:,:),
pointer :: mask2dt => null()
160 real,
dimension(:,:),
pointer :: mask2dbu => null()
161 real,
dimension(:,:),
pointer :: mask2dcu => null()
162 real,
dimension(:,:),
pointer :: mask2dcv => null()
163 real,
dimension(:,:,:),
pointer :: mask3dtl => null()
164 real,
dimension(:,:,:),
pointer :: mask3dbl => null()
165 real,
dimension(:,:,:),
pointer :: mask3dcul => null()
166 real,
dimension(:,:,:),
pointer :: mask3dcvl => null()
167 real,
dimension(:,:,:),
pointer :: mask3dti => null()
168 real,
dimension(:,:,:),
pointer :: mask3dbi => null()
169 real,
dimension(:,:,:),
pointer :: mask3dcui => null()
170 real,
dimension(:,:,:),
pointer :: mask3dcvi => null()
174 #define DIAG_ALLOC_CHUNK_SIZE 100 176 integer :: next_free_diag_id
179 real :: missing_value = -1.0e+34
182 integer :: num_diag_coords
187 type(
axes_grp),
dimension(:),
allocatable :: remap_axeszl, remap_axeszi
188 type(
axes_grp),
dimension(:),
allocatable :: remap_axestl, remap_axesbl, remap_axescul, remap_axescvl
189 type(
axes_grp),
dimension(:),
allocatable :: remap_axesti, remap_axesbi, remap_axescui, remap_axescvi
192 real,
dimension(:,:,:),
pointer :: h => null()
193 real,
dimension(:,:,:),
pointer :: t => null()
194 real,
dimension(:,:,:),
pointer :: s => null()
198 #if defined(DEBUG) || defined(__DO_SAFETY_CHECKS__) 201 real,
dimension(:,:,:),
allocatable :: h_old
212 subroutine set_axes_info(G, GV, param_file, diag_cs, set_vertical)
216 type(
diag_ctrl),
intent(inout) :: diag_cs
217 logical,
optional,
intent(in) :: set_vertical
220 integer :: id_xq, id_yq, id_zl, id_zi, id_xh, id_yh
222 real :: zlev(gv%ke), zinter(gv%ke+1)
225 set_vert = .true. ;
if (
present(set_vertical)) set_vert = set_vertical
228 id_xq = diag_axis_init(
'xq', g%gridLonB(g%isgB:g%iegB), g%x_axis_units,
'x', &
229 'q point nominal longitude', domain2=g%Domain%mpp_domain)
230 id_yq = diag_axis_init(
'yq', g%gridLatB(g%jsgB:g%jegB), g%y_axis_units,
'y', &
231 'q point nominal latitude', domain2=g%Domain%mpp_domain)
233 id_xq = diag_axis_init(
'xq', g%gridLonB(g%isg:g%ieg), g%x_axis_units,
'x', &
234 'q point nominal longitude', domain2=g%Domain%mpp_domain)
235 id_yq = diag_axis_init(
'yq', g%gridLatB(g%jsg:g%jeg), g%y_axis_units,
'y', &
236 'q point nominal latitude', domain2=g%Domain%mpp_domain)
238 id_xh = diag_axis_init(
'xh', g%gridLonT(g%isg:g%ieg), g%x_axis_units,
'x', &
239 'h point nominal longitude', domain2=g%Domain%mpp_domain)
240 id_yh = diag_axis_init(
'yh', g%gridLatT(g%jsg:g%jeg), g%y_axis_units,
'y', &
241 'h point nominal latitude', domain2=g%Domain%mpp_domain)
245 zinter(1:nz+1) = gv%sInterface(1:nz+1)
246 zlev(1:nz) = gv%sLayer(1:nz)
247 id_zl = diag_axis_init(
'zl', zlev, trim(gv%zAxisUnits),
'z', &
248 'Layer '//trim(gv%zAxisLongName), &
249 direction=gv%direction)
250 id_zi = diag_axis_init(
'zi', zinter, trim(gv%zAxisUnits),
'z', &
251 'Interface '//trim(gv%zAxisLongName), &
252 direction=gv%direction)
254 id_zl = -1 ; id_zi = -1
259 v_cell_method=
'point', is_interface=.true.)
261 v_cell_method=
'mean', is_layer=.true.)
265 x_cell_method=
'mean', y_cell_method=
'mean', v_cell_method=
'mean', &
266 is_h_point=.true., is_layer=.true., xyave_axes=diag_cs%axesZL)
268 x_cell_method=
'point', y_cell_method=
'point', v_cell_method=
'mean', &
269 is_q_point=.true., is_layer=.true.)
271 x_cell_method=
'point', y_cell_method=
'mean', v_cell_method=
'mean', &
272 is_u_point=.true., is_layer=.true., xyave_axes=diag_cs%axesZL)
274 x_cell_method=
'mean', y_cell_method=
'point', v_cell_method=
'mean', &
275 is_v_point=.true., is_layer=.true., xyave_axes=diag_cs%axesZL)
279 x_cell_method=
'mean', y_cell_method=
'mean', v_cell_method=
'point', &
280 is_h_point=.true., is_interface=.true., xyave_axes=diag_cs%axesZi)
282 x_cell_method=
'point', y_cell_method=
'point', v_cell_method=
'point', &
283 is_q_point=.true., is_interface=.true.)
285 x_cell_method=
'point', y_cell_method=
'mean', v_cell_method=
'point', &
286 is_u_point=.true., is_interface=.true., xyave_axes=diag_cs%axesZi)
288 x_cell_method=
'mean', y_cell_method=
'point', v_cell_method=
'point', &
289 is_v_point=.true., is_interface=.true., xyave_axes=diag_cs%axesZi)
293 x_cell_method=
'mean', y_cell_method=
'mean', is_h_point=.true.)
295 x_cell_method=
'point', y_cell_method=
'point', is_q_point=.true.)
297 x_cell_method=
'point', y_cell_method=
'mean', is_u_point=.true.)
299 x_cell_method=
'mean', y_cell_method=
'point', is_v_point=.true.)
301 if (diag_cs%num_diag_coords>0)
then 302 allocate(diag_cs%remap_axesZL(diag_cs%num_diag_coords))
303 allocate(diag_cs%remap_axesTL(diag_cs%num_diag_coords))
304 allocate(diag_cs%remap_axesBL(diag_cs%num_diag_coords))
305 allocate(diag_cs%remap_axesCuL(diag_cs%num_diag_coords))
306 allocate(diag_cs%remap_axesCvL(diag_cs%num_diag_coords))
307 allocate(diag_cs%remap_axesZi(diag_cs%num_diag_coords))
308 allocate(diag_cs%remap_axesTi(diag_cs%num_diag_coords))
309 allocate(diag_cs%remap_axesBi(diag_cs%num_diag_coords))
310 allocate(diag_cs%remap_axesCui(diag_cs%num_diag_coords))
311 allocate(diag_cs%remap_axesCvi(diag_cs%num_diag_coords))
314 do i=1, diag_cs%num_diag_coords
316 call diag_remap_configure_axes(diag_cs%diag_remap_cs(i), gv, param_file)
319 if (diag_remap_axes_configured(diag_cs%diag_remap_cs(i)))
then 323 call diag_remap_get_axes_info(diag_cs%diag_remap_cs(i), nz, id_zl, id_zi)
327 nz=nz, vertical_coordinate_number=i, &
328 v_cell_method=
'mean', &
329 is_h_point=.true., is_layer=.true., is_native=.false., needs_remapping=.true.)
330 call define_axes_group(diag_cs, (/ id_xh, id_yh, id_zl /), diag_cs%remap_axesTL(i), &
331 nz=nz, vertical_coordinate_number=i, &
332 x_cell_method=
'mean', y_cell_method=
'mean', v_cell_method=
'mean', &
333 is_h_point=.true., is_layer=.true., is_native=.false., needs_remapping=.true., &
334 xyave_axes=diag_cs%remap_axesZL(i))
337 call define_axes_group(diag_cs, (/ id_xq, id_yq, id_zl /), diag_cs%remap_axesBL(i), &
338 nz=nz, vertical_coordinate_number=i, &
339 x_cell_method=
'point', y_cell_method=
'point', v_cell_method=
'mean', &
340 is_q_point=.true., is_layer=.true., is_native=.false.)
342 call define_axes_group(diag_cs, (/ id_xq, id_yh, id_zl /), diag_cs%remap_axesCuL(i), &
343 nz=nz, vertical_coordinate_number=i, &
344 x_cell_method=
'point', y_cell_method=
'mean', v_cell_method=
'mean', &
345 is_u_point=.true., is_layer=.true., is_native=.false., needs_remapping=.true., &
346 xyave_axes=diag_cs%remap_axesZL(i))
348 call define_axes_group(diag_cs, (/ id_xh, id_yq, id_zl /), diag_cs%remap_axesCvL(i), &
349 nz=nz, vertical_coordinate_number=i, &
350 x_cell_method=
'mean', y_cell_method=
'point', v_cell_method=
'mean', &
351 is_v_point=.true., is_layer=.true., is_native=.false., needs_remapping=.true., &
352 xyave_axes=diag_cs%remap_axesZL(i))
356 nz=nz, vertical_coordinate_number=i, &
357 v_cell_method=
'point', &
358 is_h_point=.true., is_interface=.true., is_native=.false., needs_interpolating=.true.)
359 call define_axes_group(diag_cs, (/ id_xh, id_yh, id_zi /), diag_cs%remap_axesTi(i), &
360 nz=nz, vertical_coordinate_number=i, &
361 x_cell_method=
'mean', y_cell_method=
'mean', v_cell_method=
'point', &
362 is_h_point=.true., is_interface=.true., is_native=.false., needs_interpolating=.true., &
363 xyave_axes=diag_cs%remap_axesZi(i))
366 call define_axes_group(diag_cs, (/ id_xq, id_yq, id_zi /), diag_cs%remap_axesBi(i), &
367 nz=nz, vertical_coordinate_number=i, &
368 x_cell_method=
'point', y_cell_method=
'point', v_cell_method=
'point', &
369 is_q_point=.true., is_interface=.true., is_native=.false.)
371 call define_axes_group(diag_cs, (/ id_xq, id_yh, id_zi /), diag_cs%remap_axesCui(i), &
372 nz=nz, vertical_coordinate_number=i, &
373 x_cell_method=
'point', y_cell_method=
'mean', v_cell_method=
'point', &
374 is_u_point=.true., is_interface=.true., is_native=.false., &
375 needs_interpolating=.true., xyave_axes=diag_cs%remap_axesZi(i))
377 call define_axes_group(diag_cs, (/ id_xh, id_yq, id_zi /), diag_cs%remap_axesCvi(i), &
378 nz=nz, vertical_coordinate_number=i, &
379 x_cell_method=
'mean', y_cell_method=
'point', v_cell_method=
'point', &
380 is_v_point=.true., is_interface=.true., is_native=.false., &
381 needs_interpolating=.true., xyave_axes=diag_cs%remap_axesZi(i))
390 integer,
optional,
intent(in) :: id_area_t
391 integer,
optional,
intent(in) :: id_area_q
394 if (
present(id_area_t))
then 395 fms_id = diag_cs%diags(id_area_t)%fms_diag_id
396 diag_cs%axesT1%id_area = fms_id
397 diag_cs%axesTi%id_area = fms_id
398 diag_cs%axesTL%id_area = fms_id
399 do i=1, diag_cs%num_diag_coords
400 diag_cs%remap_axesTL(i)%id_area = fms_id
404 if (
present(id_area_q))
then 405 fms_id = diag_cs%diags(id_area_q)%fms_diag_id
406 diag_cs%axesB1%id_area = fms_id
407 diag_cs%axesBi%id_area = fms_id
408 diag_cs%axesBL%id_area = fms_id
409 do i=1, diag_cs%num_diag_coords
410 diag_cs%remap_axesBL(i)%id_area = fms_id
418 integer,
optional,
intent(in) :: id_vol_t
421 if (
present(id_vol_t))
then 422 fms_id = diag_cs%diags(id_vol_t)%fms_diag_id
423 call mom_error(fatal,
"diag_register_volume_ids: not implemented yet!")
428 subroutine define_axes_group(diag_cs, handles, axes, nz, vertical_coordinate_number, &
429 x_cell_method, y_cell_method, v_cell_method, &
430 is_h_point, is_q_point, is_u_point, is_v_point, &
431 is_layer, is_interface, &
432 is_native, needs_remapping, needs_interpolating, &
435 integer,
dimension(:),
intent(in) :: handles
437 integer,
optional,
intent(in) :: nz
438 integer,
optional,
intent(in) :: vertical_coordinate_number
439 character(len=*),
optional,
intent(in) :: x_cell_method
440 character(len=*),
optional,
intent(in) :: y_cell_method
441 character(len=*),
optional,
intent(in) :: v_cell_method
442 logical,
optional,
intent(in) :: is_h_point
443 logical,
optional,
intent(in) :: is_q_point
444 logical,
optional,
intent(in) :: is_u_point
445 logical,
optional,
intent(in) :: is_v_point
446 logical,
optional,
intent(in) :: is_layer
447 logical,
optional,
intent(in) :: is_interface
448 logical,
optional,
intent(in) :: is_native
449 logical,
optional,
intent(in) :: needs_remapping
451 logical,
optional,
intent(in) :: needs_interpolating
453 type(
axes_grp),
optional,
target :: xyave_axes
458 if (n<1 .or. n>3)
call mom_error(fatal,
"define_axes_group: wrong size for list of handles!")
459 allocate( axes%handles(n) )
460 axes%id =
i2s(handles, n)
462 axes%handles(:) = handles(:)
463 axes%diag_cs => diag_cs
464 if (
present(x_cell_method))
then 465 if (axes%rank<2)
call mom_error(fatal,
'define_axes_group: ' // &
466 'Can not set x_cell_method for rank<2.')
467 axes%x_cell_method = trim(x_cell_method)
469 axes%x_cell_method =
'' 471 if (
present(y_cell_method))
then 472 if (axes%rank<2)
call mom_error(fatal,
'define_axes_group: ' // &
473 'Can not set y_cell_method for rank<2.')
474 axes%y_cell_method = trim(y_cell_method)
476 axes%y_cell_method =
'' 478 if (
present(v_cell_method))
then 479 if (axes%rank/=1 .and. axes%rank/=3)
call mom_error(fatal,
'define_axes_group: ' // &
480 'Can not set v_cell_method for rank<>1 or 3.')
481 axes%v_cell_method = trim(v_cell_method)
483 axes%v_cell_method =
'' 485 if (
present(nz)) axes%nz = nz
486 if (
present(vertical_coordinate_number)) axes%vertical_coordinate_number = vertical_coordinate_number
487 if (
present(is_h_point)) axes%is_h_point = is_h_point
488 if (
present(is_q_point)) axes%is_q_point = is_q_point
489 if (
present(is_u_point)) axes%is_u_point = is_u_point
490 if (
present(is_v_point)) axes%is_v_point = is_v_point
491 if (
present(is_layer)) axes%is_layer = is_layer
492 if (
present(is_interface)) axes%is_interface = is_interface
493 if (
present(is_native)) axes%is_native = is_native
494 if (
present(needs_remapping)) axes%needs_remapping = needs_remapping
495 if (
present(needs_interpolating)) axes%needs_interpolating = needs_interpolating
496 if (
present(xyave_axes)) axes%xyave_axes => xyave_axes
502 type(
diag_ctrl),
intent(inout) :: diag_cs
508 diag_cs%is = g%isc - (g%isd-1) ; diag_cs%ie = g%iec - (g%isd-1)
509 diag_cs%js = g%jsc - (g%jsd-1) ; diag_cs%je = g%jec - (g%jsd-1)
510 diag_cs%isd = g%isd ; diag_cs%ied = g%ied
511 diag_cs%jsd = g%jsd ; diag_cs%jed = g%jed
515 subroutine post_data_0d(diag_field_id, field, diag_cs, is_static)
516 integer,
intent(in) :: diag_field_id
517 real,
intent(in) :: field
518 type(
diag_ctrl),
target,
intent(in) :: diag_cs
519 logical,
optional,
intent(in) :: is_static
529 logical :: used, is_stat
530 type(
diag_type),
pointer :: diag => null()
533 is_stat = .false. ;
if (
present(is_static)) is_stat = is_static
537 call assert(diag_field_id < diag_cs%next_free_diag_id, &
538 'post_data_0d: Unregistered diagnostic id')
539 diag => diag_cs%diags(diag_field_id)
540 do while (
associated(diag))
542 used = send_data(diag%fms_diag_id, field)
543 elseif (diag_cs%ave_enabled)
then 544 used = send_data(diag%fms_diag_id, field, diag_cs%time_end)
552 subroutine post_data_1d_k(diag_field_id, field, diag_cs, is_static)
553 integer,
intent(in) :: diag_field_id
554 real,
intent(in) :: field(:)
555 type(
diag_ctrl),
target,
intent(in) :: diag_cs
556 logical,
optional,
intent(in) :: is_static
567 integer :: isv, iev, jsv, jev
568 type(
diag_type),
pointer :: diag => null()
571 is_stat = .false. ;
if (
present(is_static)) is_stat = is_static
574 call assert(diag_field_id < diag_cs%next_free_diag_id, &
575 'post_data_1d_k: Unregistered diagnostic id')
576 diag => diag_cs%diags(diag_field_id)
577 do while (
associated(diag))
579 used = send_data(diag%fms_diag_id, field)
580 elseif (diag_cs%ave_enabled)
then 581 used = send_data(diag%fms_diag_id, field, diag_cs%time_end, weight=diag_cs%time_int)
589 subroutine post_data_2d(diag_field_id, field, diag_cs, is_static, mask)
590 integer,
intent(in) :: diag_field_id
591 real,
intent(in) :: field(:,:)
592 type(
diag_ctrl),
target,
intent(in) :: diag_cs
593 logical,
optional,
intent(in) :: is_static
594 real,
optional,
intent(in) :: mask(:,:)
604 type(
diag_type),
pointer :: diag => null()
609 call assert(diag_field_id < diag_cs%next_free_diag_id, &
610 'post_data_2d: Unregistered diagnostic id')
611 diag => diag_cs%diags(diag_field_id)
612 do while (
associated(diag))
622 real,
target,
intent(in) :: field(:,:)
624 logical,
optional,
intent(in) :: is_static
625 real,
optional,
intent(in) :: mask(:,:)
634 real,
dimension(:,:),
pointer :: locfield => null()
635 logical :: used, is_stat
636 integer :: isv, iev, jsv, jev
638 is_stat = .false. ;
if (
present(is_static)) is_stat = is_static
645 isv = diag_cs%is ; iev = diag_cs%ie ; jsv = diag_cs%js ; jev = diag_cs%je
647 if (
size(field,1) == diag_cs%ied-diag_cs%isd +1 )
then 648 isv = diag_cs%is ; iev = diag_cs%ie
649 elseif (
size(field,1) == diag_cs%ied-diag_cs%isd +2 )
then 650 isv = diag_cs%is ; iev = diag_cs%ie+1
651 elseif (
size(field,1) == diag_cs%ie-diag_cs%is +1 )
then 652 isv = 1 ; iev = diag_cs%ie + 1-diag_cs%is
653 elseif (
size(field,1) == diag_cs%ie-diag_cs%is +2 )
then 654 isv = 1 ; iev = diag_cs%ie + 2-diag_cs%is
656 call mom_error(fatal,
"post_data_2d_low: peculiar size in i-direction")
658 if (
size(field,2) == diag_cs%jed-diag_cs%jsd +1 )
then 659 jsv = diag_cs%js ; jev = diag_cs%je
660 elseif (
size(field,2) == diag_cs%jed-diag_cs%jsd +2 )
then 661 jsv = diag_cs%js ; jev = diag_cs%je+1
662 elseif (
size(field,2) == diag_cs%je-diag_cs%js +1 )
then 663 jsv = 1 ; jev = diag_cs%je + 1-diag_cs%js
664 elseif (
size(field,1) == diag_cs%je-diag_cs%js +2 )
then 665 jsv = 1 ; jev = diag_cs%je + 2-diag_cs%js
667 call mom_error(fatal,
"post_data_2d_low: peculiar size in j-direction")
670 if (diag%conversion_factor/=0.)
then 671 allocate( locfield( lbound(field,1):ubound(field,1), lbound(field,2):ubound(field,2) ) )
672 locfield(isv:iev,jsv:jev) = field(isv:iev,jsv:jev) * diag%conversion_factor
678 if (
present(mask))
then 679 call assert(
size(locfield) ==
size(mask), &
680 'post_data_2d_low is_stat: mask size mismatch: '//diag%debug_str)
681 used = send_data(diag%fms_diag_id, locfield, &
682 is_in=isv, js_in=jsv, ie_in=iev, je_in=jev, rmask=mask)
687 used = send_data(diag%fms_diag_id, locfield, &
688 is_in=isv, js_in=jsv, ie_in=iev, je_in=jev)
690 elseif (diag_cs%ave_enabled)
then 691 if (
present(mask))
then 692 call assert(
size(locfield) ==
size(mask), &
693 'post_data_2d_low: mask size mismatch: '//diag%debug_str)
694 used = send_data(diag%fms_diag_id, locfield, diag_cs%time_end, &
695 is_in=isv, js_in=jsv, ie_in=iev, je_in=jev, &
696 weight=diag_cs%time_int, rmask=mask)
697 elseif(
associated(diag%mask2d))
then 698 used = send_data(diag%fms_diag_id, locfield, diag_cs%time_end, &
699 is_in=isv, js_in=jsv, ie_in=iev, je_in=jev, &
700 weight=diag_cs%time_int, rmask=diag%mask2d)
702 used = send_data(diag%fms_diag_id, locfield, diag_cs%time_end, &
703 is_in=isv, js_in=jsv, ie_in=iev, je_in=jev, &
704 weight=diag_cs%time_int)
707 if (diag%conversion_factor/=0.)
deallocate( locfield )
711 subroutine post_data_3d(diag_field_id, field, diag_cs, is_static, mask, alt_h)
713 integer,
intent(in) :: diag_field_id
714 real,
intent(in) :: field(:,:,:)
715 type(
diag_ctrl),
target,
intent(in) :: diag_cs
716 logical,
optional,
intent(in) :: is_static
717 real,
optional,
intent(in) :: mask(:,:,:)
718 real,
target,
optional,
intent(in) :: alt_h(:,:,:)
728 type(
diag_type),
pointer :: diag => null()
729 integer :: nz, i, j, k
730 real,
dimension(:,:,:),
allocatable :: remapped_field
731 logical :: staggered_in_x, staggered_in_y
732 real,
dimension(:,:,:),
pointer :: h_diag
734 if(
present(alt_h))
then 744 call assert(diag_field_id < diag_cs%next_free_diag_id, &
745 'post_data_3d: Unregistered diagnostic id')
746 diag => diag_cs%diags(diag_field_id)
747 do while (
associated(diag))
748 call assert(
associated(diag%axes),
'post_data_3d: axes is not associated')
750 staggered_in_x = diag%axes%is_u_point .or. diag%axes%is_q_point
751 staggered_in_y = diag%axes%is_v_point .or. diag%axes%is_q_point
753 if (diag%v_extensive .and. .not.diag%axes%is_native)
then 755 if (
present(mask))
then 756 call mom_error(fatal,
"post_data_3d: no mask for regridded field.")
760 allocate(remapped_field(
size(field,1),
size(field,2), diag%axes%nz))
761 call vertically_reintegrate_diag_field( &
762 diag_cs%diag_remap_cs(diag%axes%vertical_coordinate_number), &
763 diag_cs%G, h_diag, staggered_in_x, staggered_in_y, &
764 diag%mask3d, diag_cs%missing_value, field, remapped_field)
766 if (
associated(diag%mask3d))
then 770 mask=diag%mask3d(:,:,:diag%axes%nz))
775 deallocate(remapped_field)
777 elseif (diag%axes%needs_remapping)
then 779 if (
present(mask))
then 780 call mom_error(fatal,
"post_data_3d: no mask for regridded field.")
784 allocate(remapped_field(
size(field,1),
size(field,2), diag%axes%nz))
785 call diag_remap_do_remap(diag_cs%diag_remap_cs( &
786 diag%axes%vertical_coordinate_number), &
787 diag_cs%G, h_diag, staggered_in_x, staggered_in_y, &
788 diag%mask3d, diag_cs%missing_value, field, remapped_field)
790 if (
associated(diag%mask3d))
then 794 mask=diag%mask3d(:,:,:diag%axes%nz))
799 deallocate(remapped_field)
801 elseif (diag%axes%needs_interpolating)
then 803 if (
present(mask))
then 804 call mom_error(fatal,
"post_data_3d: no mask for regridded field.")
808 allocate(remapped_field(
size(field,1),
size(field,2), diag%axes%nz+1))
809 call vertically_interpolate_diag_field(diag_cs%diag_remap_cs( &
810 diag%axes%vertical_coordinate_number), &
811 diag_cs%G, h_diag, staggered_in_x, staggered_in_y, &
812 diag%mask3d, diag_cs%missing_value, field, remapped_field)
814 if (
associated(diag%mask3d))
then 818 mask=diag%mask3d(:,:,:diag%axes%nz+1))
823 deallocate(remapped_field)
836 real,
target,
intent(in) :: field(:,:,:)
838 logical,
optional,
intent(in) :: is_static
839 real,
optional,
intent(in) :: mask(:,:,:)
848 real,
dimension(:,:,:),
pointer :: locfield => null()
851 integer :: isv, iev, jsv, jev
853 is_stat = .false. ;
if (
present(is_static)) is_stat = is_static
860 isv = diag_cs%is ; iev = diag_cs%ie ; jsv = diag_cs%js ; jev = diag_cs%je
862 if (
size(field,1) == diag_cs%ied-diag_cs%isd +1 )
then 863 isv = diag_cs%is ; iev = diag_cs%ie
864 elseif (
size(field,1) == diag_cs%ied-diag_cs%isd +2 )
then 865 isv = diag_cs%is ; iev = diag_cs%ie+1
866 elseif (
size(field,1) == diag_cs%ie-diag_cs%is +1 )
then 867 isv = 1 ; iev = diag_cs%ie + 1-diag_cs%is
868 elseif (
size(field,1) == diag_cs%ie-diag_cs%is +2 )
then 869 isv = 1 ; iev = diag_cs%ie + 2-diag_cs%is
871 call mom_error(fatal,
"post_data_3d_low: peculiar size in i-direction")
873 if (
size(field,2) == diag_cs%jed-diag_cs%jsd +1 )
then 874 jsv = diag_cs%js ; jev = diag_cs%je
875 elseif (
size(field,2) == diag_cs%jed-diag_cs%jsd +2 )
then 876 jsv = diag_cs%js ; jev = diag_cs%je+1
877 elseif (
size(field,2) == diag_cs%je-diag_cs%js +1 )
then 878 jsv = 1 ; jev = diag_cs%je + 1-diag_cs%js
879 elseif (
size(field,1) == diag_cs%je-diag_cs%js +2 )
then 880 jsv = 1 ; jev = diag_cs%je + 2-diag_cs%js
882 call mom_error(fatal,
"post_data_3d_low: peculiar size in j-direction")
885 if (diag%conversion_factor/=0.)
then 886 allocate( locfield( lbound(field,1):ubound(field,1), lbound(field,2):ubound(field,2), &
887 lbound(field,3):ubound(field,3) ) )
888 locfield(isv:iev,jsv:jev,:) = field(isv:iev,jsv:jev,:) * diag%conversion_factor
893 if (diag%fms_diag_id>0)
then 895 if (
present(mask))
then 896 call assert(
size(locfield) ==
size(mask), &
897 'post_data_3d_low is_stat: mask size mismatch: '//diag%debug_str)
898 used = send_data(diag%fms_diag_id, locfield, &
899 is_in=isv, js_in=jsv, ie_in=iev, je_in=jev, rmask=mask)
904 used = send_data(diag%fms_diag_id, locfield, &
905 is_in=isv, js_in=jsv, ie_in=iev, je_in=jev)
907 elseif (diag_cs%ave_enabled)
then 908 if (
present(mask))
then 909 call assert(
size(locfield) ==
size(mask), &
910 'post_data_3d_low: mask size mismatch: '//diag%debug_str)
911 used = send_data(diag%fms_diag_id, locfield, diag_cs%time_end, &
912 is_in=isv, js_in=jsv, ie_in=iev, je_in=jev, &
913 weight=diag_cs%time_int, rmask=mask)
914 elseif(
associated(diag%mask3d))
then 915 call assert(
size(locfield) ==
size(diag%mask3d), &
916 'post_data_3d_low: mask3d size mismatch: '//diag%debug_str)
917 used = send_data(diag%fms_diag_id, locfield, diag_cs%time_end, &
918 is_in=isv, js_in=jsv, ie_in=iev, je_in=jev, &
919 weight=diag_cs%time_int, rmask=diag%mask3d)
921 used = send_data(diag%fms_diag_id, locfield, diag_cs%time_end, &
922 is_in=isv, js_in=jsv, ie_in=iev, je_in=jev, &
923 weight=diag_cs%time_int)
927 if (diag%fms_xyave_diag_id>0)
then 930 if (diag%conversion_factor/=0.)
deallocate( locfield )
937 real,
target,
intent(in) :: field(:,:,:)
940 real,
dimension(size(field,3)) :: averaged_field
941 logical :: staggered_in_x, staggered_in_y, used
942 integer :: nz, remap_nz, coord
944 if (.not. diag_cs%ave_enabled)
then 948 staggered_in_x = diag%axes%is_u_point .or. diag%axes%is_q_point
949 staggered_in_y = diag%axes%is_v_point .or. diag%axes%is_q_point
951 if (diag%axes%is_native)
then 953 staggered_in_x, staggered_in_y, &
954 diag%axes%is_layer, diag%v_extensive, &
955 diag_cs%missing_value, field, averaged_field)
958 coord = diag%axes%vertical_coordinate_number
959 remap_nz = diag_cs%diag_remap_cs(coord)%nz
961 call assert(diag_cs%diag_remap_cs(coord)%initialized, &
962 'post_xy_average: remap_cs not initialized.')
964 call assert(implies(diag%axes%is_layer, nz == remap_nz), &
965 'post_xy_average: layer field dimension mismatch.')
966 call assert(implies(.not. diag%axes%is_layer, nz == remap_nz+1), &
967 'post_xy_average: interface field dimension mismatch.')
970 staggered_in_x, staggered_in_y, &
971 diag%axes%is_layer, diag%v_extensive, &
972 diag_cs%missing_value, field, averaged_field)
975 used = send_data(diag%fms_xyave_diag_id, averaged_field, diag_cs%time_end, &
976 weight=diag_cs%time_int)
980 real,
intent(in) :: time_int_in
981 type(time_type),
intent(in) :: time_end_in
982 type(
diag_ctrl),
intent(inout) :: diag_cs
994 diag_cs%time_int = time_int_in
995 diag_cs%time_end = time_end_in
996 diag_cs%ave_enabled = .true.
1006 diag_cs%time_int = 0.0
1007 diag_cs%ave_enabled = .false.
1015 real,
optional,
intent(out) :: time_int
1016 type(time_type),
optional,
intent(out) :: time_end
1017 logical :: query_averaging_enabled
1024 if (
present(time_int)) time_int = diag_cs%time_int
1025 if (
present(time_end)) time_end = diag_cs%time_end
1026 query_averaging_enabled = diag_cs%ave_enabled
1031 type(time_type) :: get_diag_time_end
1039 get_diag_time_end = diag_cs%time_end
1044 long_name, units, missing_value, range, mask_variant, standard_name, &
1045 verbose, do_not_log, err_msg, interp_method, tile_count, cmor_field_name, &
1046 cmor_long_name, cmor_units, cmor_standard_name, cell_methods, &
1047 x_cell_method, y_cell_method, v_cell_method, conversion, v_extensive)
1048 character(len=*),
intent(in) :: module_name
1049 character(len=*),
intent(in) :: field_name
1050 type(
axes_grp),
target,
intent(in) :: axes
1051 type(time_type),
intent(in) :: init_time
1052 character(len=*),
optional,
intent(in) :: long_name
1053 character(len=*),
optional,
intent(in) :: units
1054 character(len=*),
optional,
intent(in) :: standard_name
1055 real,
optional,
intent(in) :: missing_value
1056 real,
optional,
intent(in) :: range(2)
1057 logical,
optional,
intent(in) :: mask_variant
1058 logical,
optional,
intent(in) :: verbose
1059 logical,
optional,
intent(in) :: do_not_log
1060 character(len=*),
optional,
intent(out):: err_msg
1061 character(len=*),
optional,
intent(in) :: interp_method
1062 integer,
optional,
intent(in) :: tile_count
1063 character(len=*),
optional,
intent(in) :: cmor_field_name
1064 character(len=*),
optional,
intent(in) :: cmor_long_name
1065 character(len=*),
optional,
intent(in) :: cmor_units
1066 character(len=*),
optional,
intent(in) :: cmor_standard_name
1067 character(len=*),
optional,
intent(in) :: cell_methods
1070 character(len=*),
optional,
intent(in) :: x_cell_method
1071 character(len=*),
optional,
intent(in) :: y_cell_method
1072 character(len=*),
optional,
intent(in) :: v_cell_method
1073 real,
optional,
intent(in) :: conversion
1074 logical,
optional,
intent(in) :: v_extensive
1076 real :: MOM_missing_value
1078 type(
axes_grp),
pointer :: remap_axes => null()
1080 character(len=256) :: new_module_name
1083 mom_missing_value = axes%diag_cs%missing_value
1084 if(
present(missing_value)) mom_missing_value = missing_value
1086 diag_cs => axes%diag_cs
1091 init_time, long_name=long_name, units=units, missing_value=mom_missing_value, &
1092 range=range, mask_variant=mask_variant, standard_name=standard_name, &
1093 verbose=verbose, do_not_log=do_not_log, err_msg=err_msg, &
1094 interp_method=interp_method, tile_count=tile_count, &
1095 cmor_field_name=cmor_field_name, cmor_long_name=cmor_long_name, &
1096 cmor_units=cmor_units, cmor_standard_name=cmor_standard_name, &
1097 cell_methods=cell_methods, x_cell_method=x_cell_method, &
1098 y_cell_method=y_cell_method, v_cell_method=v_cell_method, &
1099 conversion=conversion, v_extensive=v_extensive)
1102 do i=1,diag_cs%num_diag_coords
1103 new_module_name = trim(module_name)//
'_'//trim(diag_cs%diag_remap_cs(i)%diag_module_suffix)
1106 if (axes%rank == 3)
then 1107 remap_axes => null()
1108 if ((axes%id .eq. diag_cs%axesTL%id))
then 1109 remap_axes => diag_cs%remap_axesTL(i)
1110 elseif(axes%id .eq. diag_cs%axesBL%id)
then 1111 remap_axes => diag_cs%remap_axesBL(i)
1112 elseif(axes%id .eq. diag_cs%axesCuL%id )
then 1113 remap_axes => diag_cs%remap_axesCuL(i)
1114 elseif(axes%id .eq. diag_cs%axesCvL%id)
then 1115 remap_axes => diag_cs%remap_axesCvL(i)
1116 elseif(axes%id .eq. diag_cs%axesTi%id)
then 1117 remap_axes => diag_cs%remap_axesTi(i)
1118 elseif(axes%id .eq. diag_cs%axesBi%id)
then 1119 remap_axes => diag_cs%remap_axesBi(i)
1120 elseif(axes%id .eq. diag_cs%axesCui%id )
then 1121 remap_axes => diag_cs%remap_axesCui(i)
1122 elseif(axes%id .eq. diag_cs%axesCvi%id)
then 1123 remap_axes => diag_cs%remap_axesCvi(i)
1128 if (
associated(remap_axes))
then 1129 if (remap_axes%needs_remapping .or. remap_axes%needs_interpolating)
then 1131 init_time, long_name=long_name, units=units, missing_value=mom_missing_value, &
1132 range=range, mask_variant=mask_variant, standard_name=standard_name, &
1133 verbose=verbose, do_not_log=do_not_log, err_msg=err_msg, &
1134 interp_method=interp_method, tile_count=tile_count, &
1135 cmor_field_name=cmor_field_name, cmor_long_name=cmor_long_name, &
1136 cmor_units=cmor_units, cmor_standard_name=cmor_standard_name, &
1137 cell_methods=cell_methods, x_cell_method=x_cell_method, &
1138 y_cell_method=y_cell_method, v_cell_method=v_cell_method, &
1139 conversion=conversion, v_extensive=v_extensive)
1141 call diag_remap_set_active(diag_cs%diag_remap_cs(i))
1155 long_name, units, missing_value, range, mask_variant, standard_name, &
1156 verbose, do_not_log, err_msg, interp_method, tile_count, cmor_field_name, &
1157 cmor_long_name, cmor_units, cmor_standard_name, cell_methods, &
1158 x_cell_method, y_cell_method, v_cell_method, conversion, v_extensive)
1159 integer,
intent(inout) :: dm_id
1160 character(len=*),
intent(in) :: module_name
1161 character(len=*),
intent(in) :: field_name
1162 type(
axes_grp),
target,
intent(in) :: axes
1163 type(time_type),
intent(in) :: init_time
1164 character(len=*),
optional,
intent(in) :: long_name
1165 character(len=*),
optional,
intent(in) :: units
1166 character(len=*),
optional,
intent(in) :: standard_name
1167 real,
optional,
intent(in) :: missing_value
1168 real,
optional,
intent(in) :: range(2)
1169 logical,
optional,
intent(in) :: mask_variant
1170 logical,
optional,
intent(in) :: verbose
1171 logical,
optional,
intent(in) :: do_not_log
1172 character(len=*),
optional,
intent(out):: err_msg
1173 character(len=*),
optional,
intent(in) :: interp_method
1174 integer,
optional,
intent(in) :: tile_count
1175 character(len=*),
optional,
intent(in) :: cmor_field_name
1176 character(len=*),
optional,
intent(in) :: cmor_long_name
1177 character(len=*),
optional,
intent(in) :: cmor_units
1178 character(len=*),
optional,
intent(in) :: cmor_standard_name
1179 character(len=*),
optional,
intent(in) :: cell_methods
1182 character(len=*),
optional,
intent(in) :: x_cell_method
1183 character(len=*),
optional,
intent(in) :: y_cell_method
1184 character(len=*),
optional,
intent(in) :: v_cell_method
1185 real,
optional,
intent(in) :: conversion
1186 logical,
optional,
intent(in) :: v_extensive
1188 real :: MOM_missing_value
1190 type(
diag_type),
pointer :: this_diag => null()
1191 integer :: fms_id, fms_xyave_id
1192 character(len=256) :: posted_cmor_units, posted_cmor_standard_name, posted_cmor_long_name, cm_string, msg
1194 mom_missing_value = axes%diag_cs%missing_value
1195 if(
present(missing_value)) mom_missing_value = missing_value
1198 diag_cs => axes%diag_cs
1202 long_name=long_name, units=units, missing_value=mom_missing_value, &
1203 range=range, mask_variant=mask_variant, standard_name=standard_name, &
1204 verbose=verbose, do_not_log=do_not_log, err_msg=err_msg, &
1205 interp_method=interp_method, tile_count=tile_count)
1207 cell_methods, x_cell_method, y_cell_method, v_cell_method, &
1208 v_extensive=v_extensive)
1209 if (
is_root_pe() .and. diag_cs%doc_unit > 0)
then 1211 if (
present(cmor_field_name)) msg =
'CMOR equivalent is "'//trim(cmor_field_name)//
'"' 1213 msg, diag_cs, long_name, units, standard_name)
1216 fms_xyave_id = diag_field_not_found
1217 if (
associated(axes%xyave_axes))
then 1219 axes%xyave_axes, init_time, &
1220 long_name=long_name, units=units, missing_value=mom_missing_value, &
1221 range=range, mask_variant=mask_variant, standard_name=standard_name, &
1222 verbose=verbose, do_not_log=do_not_log, err_msg=err_msg, &
1223 interp_method=interp_method, tile_count=tile_count)
1225 cell_methods, v_cell_method, v_extensive=v_extensive)
1226 if (
is_root_pe() .and. diag_cs%doc_unit > 0)
then 1228 if (
present(cmor_field_name)) msg =
'CMOR equivalent is "'//trim(cmor_field_name)//
'_xyave"' 1229 call log_available_diag(fms_xyave_id>0, module_name, trim(field_name)//
'_xyave', cm_string, &
1230 msg, diag_cs, long_name, units, standard_name)
1234 if (fms_id /= diag_field_not_found .or. fms_xyave_id /= diag_field_not_found)
then 1235 call add_diag_to_list(diag_cs, dm_id, fms_id, this_diag, axes, module_name, field_name, msg)
1236 this_diag%fms_xyave_diag_id = fms_xyave_id
1238 if (
present(v_extensive)) this_diag%v_extensive = v_extensive
1239 if (
present(conversion)) this_diag%conversion_factor = conversion
1244 if (
present(cmor_field_name))
then 1246 posted_cmor_units =
"not provided" 1247 posted_cmor_standard_name =
"not provided" 1248 posted_cmor_long_name =
"not provided" 1252 if (
present(units)) posted_cmor_units = units
1253 if (
present(standard_name)) posted_cmor_standard_name = standard_name
1254 if (
present(long_name)) posted_cmor_long_name = long_name
1257 if (
present(cmor_units)) posted_cmor_units = cmor_units
1258 if (
present(cmor_standard_name)) posted_cmor_standard_name = cmor_standard_name
1259 if (
present(cmor_long_name)) posted_cmor_long_name = cmor_long_name
1262 long_name=trim(posted_cmor_long_name), units=trim(posted_cmor_units), &
1263 missing_value=mom_missing_value, range=range, mask_variant=mask_variant, &
1264 standard_name=trim(posted_cmor_standard_name), verbose=verbose, do_not_log=do_not_log, &
1265 err_msg=err_msg, interp_method=interp_method, tile_count=tile_count)
1267 cell_methods, x_cell_method, y_cell_method, v_cell_method, &
1268 v_extensive=v_extensive)
1269 if (
is_root_pe() .and. diag_cs%doc_unit > 0)
then 1270 msg =
'native name is "'//trim(field_name)//
'"' 1272 msg, diag_cs, posted_cmor_long_name, posted_cmor_units, &
1273 posted_cmor_standard_name)
1276 fms_xyave_id = diag_field_not_found
1277 if (
associated(axes%xyave_axes))
then 1279 axes%xyave_axes, init_time, &
1280 long_name=trim(posted_cmor_long_name), units=trim(posted_cmor_units), &
1281 missing_value=mom_missing_value, range=range, mask_variant=mask_variant, &
1282 standard_name=trim(posted_cmor_standard_name), verbose=verbose, do_not_log=do_not_log, &
1283 err_msg=err_msg, interp_method=interp_method, tile_count=tile_count)
1285 cell_methods, v_cell_method, v_extensive=v_extensive)
1286 if (
is_root_pe() .and. diag_cs%doc_unit > 0)
then 1287 msg =
'native name is "'//trim(field_name)//
'_xyave"' 1288 call log_available_diag(fms_xyave_id>0, module_name, trim(cmor_field_name)//
'_xyave', cm_string, &
1289 msg, diag_cs, posted_cmor_long_name, posted_cmor_units, &
1290 posted_cmor_standard_name)
1294 if (fms_id /= diag_field_not_found .or. fms_xyave_id /= diag_field_not_found)
then 1295 call add_diag_to_list(diag_cs, dm_id, fms_id, this_diag, axes, module_name, field_name, msg)
1296 this_diag%fms_xyave_diag_id = fms_xyave_id
1298 if (
present(v_extensive)) this_diag%v_extensive = v_extensive
1299 if (
present(conversion)) this_diag%conversion_factor = conversion
1309 long_name, units, missing_value, range, mask_variant, standard_name, &
1310 verbose, do_not_log, err_msg, interp_method, tile_count)
1311 character(len=*),
intent(in) :: module_name
1312 character(len=*),
intent(in) :: field_name
1313 type(
axes_grp),
target,
intent(in) :: axes
1314 type(time_type),
intent(in) :: init_time
1315 character(len=*),
optional,
intent(in) :: long_name
1316 character(len=*),
optional,
intent(in) :: units
1317 character(len=*),
optional,
intent(in) :: standard_name
1318 real,
optional,
intent(in) :: missing_value
1319 real,
optional,
intent(in) :: range(2)
1320 logical,
optional,
intent(in) :: mask_variant
1321 logical,
optional,
intent(in) :: verbose
1322 logical,
optional,
intent(in) :: do_not_log
1323 character(len=*),
optional,
intent(out):: err_msg
1324 character(len=*),
optional,
intent(in) :: interp_method
1325 integer,
optional,
intent(in) :: tile_count
1327 integer :: fms_id, area_id
1330 area_id = axes%id_area
1333 if (
present(interp_method) .or. axes%is_h_point)
then 1337 init_time, long_name=long_name, units=units, missing_value=missing_value, &
1338 range=range, mask_variant=mask_variant, standard_name=standard_name, &
1339 verbose=verbose, do_not_log=do_not_log, err_msg=err_msg, &
1340 interp_method=interp_method, tile_count=tile_count, area=area_id)
1343 init_time, long_name=long_name, units=units, missing_value=missing_value, &
1344 range=range, mask_variant=mask_variant, standard_name=standard_name, &
1345 verbose=verbose, do_not_log=do_not_log, err_msg=err_msg, &
1346 interp_method=interp_method, tile_count=tile_count)
1352 init_time, long_name=long_name, units=units, missing_value=missing_value, &
1353 range=range, mask_variant=mask_variant, standard_name=standard_name, &
1354 verbose=verbose, do_not_log=do_not_log, err_msg=err_msg, &
1355 interp_method=
'none', tile_count=tile_count, area=area_id)
1358 init_time, long_name=long_name, units=units, missing_value=missing_value, &
1359 range=range, mask_variant=mask_variant, standard_name=standard_name, &
1360 verbose=verbose, do_not_log=do_not_log, err_msg=err_msg, &
1361 interp_method=
'none', tile_count=tile_count)
1370 subroutine add_diag_to_list(diag_cs, dm_id, fms_id, this_diag, axes, module_name, field_name, msg)
1372 integer,
intent(inout) :: dm_id
1373 integer,
intent(in) :: fms_id
1375 type(
axes_grp),
target,
intent(in) :: axes
1376 character(len=*),
intent(in) :: module_name
1377 character(len=*),
intent(in) :: field_name
1378 character(len=*),
intent(in) :: msg
1384 call assert(
associated(this_diag), trim(msg)//
': diag_type allocation failed')
1386 this_diag%fms_diag_id = fms_id
1387 this_diag%debug_str = trim(module_name)//
"-"//trim(field_name)
1389 this_diag%axes => axes
1395 x_cell_method, y_cell_method, v_cell_method, v_extensive)
1396 integer,
intent(in) :: id
1398 character(len=*),
intent(out) :: ostring
1399 character(len=*),
optional,
intent(in) :: cell_methods
1402 character(len=*),
optional,
intent(in) :: x_cell_method
1403 character(len=*),
optional,
intent(in) :: y_cell_method
1404 character(len=*),
optional,
intent(in) :: v_cell_method
1405 logical,
optional,
intent(in) :: v_extensive
1407 character(len=9) :: axis_name
1410 if (
present(cell_methods))
then 1411 if (
present(x_cell_method) .or.
present(y_cell_method) .or.
present(v_cell_method) &
1412 .or.
present(v_extensive))
then 1413 call mom_error(fatal,
"attach_cell_methods: " // &
1414 'Individual direction cell method was specified along with a "cell_methods" string.')
1416 if (len(trim(cell_methods))>0)
then 1417 call diag_field_add_attribute(id,
'cell_methods', trim(cell_methods))
1418 ostring = trim(cell_methods)
1421 if (
present(x_cell_method))
then 1422 if (len(trim(x_cell_method))>0)
then 1423 call get_diag_axis_name(axes%handles(1), axis_name)
1424 call diag_field_add_attribute(id,
'cell_methods', trim(axis_name)//
':'//trim(x_cell_method))
1425 ostring = trim(adjustl(ostring))//
' '//trim(axis_name)//
':'//trim(x_cell_method)
1428 if (len(trim(axes%x_cell_method))>0)
then 1429 call get_diag_axis_name(axes%handles(1), axis_name)
1430 call diag_field_add_attribute(id,
'cell_methods', trim(axis_name)//
':'//trim(axes%x_cell_method))
1431 ostring = trim(adjustl(ostring))//
' '//trim(axis_name)//
':'//trim(axes%x_cell_method)
1434 if (
present(y_cell_method))
then 1435 if (len(trim(y_cell_method))>0)
then 1436 call get_diag_axis_name(axes%handles(2), axis_name)
1437 call diag_field_add_attribute(id,
'cell_methods', trim(axis_name)//
':'//trim(y_cell_method))
1438 ostring = trim(adjustl(ostring))//
' '//trim(axis_name)//
':'//trim(y_cell_method)
1441 if (len(trim(axes%y_cell_method))>0)
then 1442 call get_diag_axis_name(axes%handles(2), axis_name)
1443 call diag_field_add_attribute(id,
'cell_methods', trim(axis_name)//
':'//trim(axes%y_cell_method))
1444 ostring = trim(adjustl(ostring))//
' '//trim(axis_name)//
':'//trim(axes%y_cell_method)
1447 if (
present(v_cell_method))
then 1448 if (
present(v_extensive))
call mom_error(fatal,
"attach_cell_methods: " // &
1449 'Vertical cell method was specified along with the vertically extensive flag.')
1450 if (len(trim(v_cell_method))>0)
then 1451 if (axes%rank==1)
then 1452 call get_diag_axis_name(axes%handles(1), axis_name)
1453 elseif (axes%rank==3)
then 1454 call get_diag_axis_name(axes%handles(3), axis_name)
1456 call diag_field_add_attribute(id,
'cell_methods', trim(axis_name)//
':'//trim(v_cell_method))
1457 ostring = trim(adjustl(ostring))//
' '//trim(axis_name)//
':'//trim(v_cell_method)
1459 elseif (
present(v_extensive))
then 1460 if (axes%rank==1)
then 1461 call get_diag_axis_name(axes%handles(1), axis_name)
1462 elseif (axes%rank==3)
then 1463 call get_diag_axis_name(axes%handles(3), axis_name)
1465 call diag_field_add_attribute(id,
'cell_methods', trim(axis_name)//
':sum')
1466 ostring = trim(adjustl(ostring))//
' '//trim(axis_name)//
':sum' 1468 if (len(trim(axes%v_cell_method))>0)
then 1469 if (axes%rank==1)
then 1470 call get_diag_axis_name(axes%handles(1), axis_name)
1471 elseif (axes%rank==3)
then 1472 call get_diag_axis_name(axes%handles(3), axis_name)
1474 call diag_field_add_attribute(id,
'cell_methods', trim(axis_name)//
':'//trim(axes%v_cell_method))
1475 ostring = trim(adjustl(ostring))//
' '//trim(axis_name)//
':'//trim(axes%v_cell_method)
1479 ostring = adjustl(ostring)
1483 long_name, units, missing_value, range, standard_name, &
1484 do_not_log, err_msg, interp_method, cmor_field_name, &
1485 cmor_long_name, cmor_units, cmor_standard_name)
1486 integer :: register_scalar_field
1487 character(len=*),
intent(in) :: module_name, field_name
1488 type(time_type),
intent(in) :: init_time
1489 type(
diag_ctrl),
intent(inout) :: diag_cs
1490 character(len=*),
optional,
intent(in) :: long_name, units, standard_name
1491 real,
optional,
intent(in) :: missing_value, range(2)
1492 logical,
optional,
intent(in) :: do_not_log
1493 character(len=*),
optional,
intent(out):: err_msg
1494 character(len=*),
optional,
intent(in) :: interp_method
1495 character(len=*),
optional,
intent(in) :: cmor_field_name, cmor_long_name
1496 character(len=*),
optional,
intent(in) :: cmor_units, cmor_standard_name
1517 real :: MOM_missing_value
1518 integer :: dm_id, fms_id
1519 type(
diag_type),
pointer :: diag => null(), cmor_diag => null()
1520 character(len=256) :: posted_cmor_units, posted_cmor_standard_name, posted_cmor_long_name
1522 mom_missing_value = diag_cs%missing_value
1523 if(
present(missing_value)) mom_missing_value = missing_value
1530 long_name=long_name, units=units, missing_value=mom_missing_value, &
1531 range=range, standard_name=standard_name, do_not_log=do_not_log, err_msg=err_msg)
1532 if (fms_id /= diag_field_not_found)
then 1535 call assert(
associated(diag),
'register_scalar_field: diag allocation failed')
1536 diag%fms_diag_id = fms_id
1537 diag%debug_str = trim(module_name)//
"-"//trim(field_name)
1540 if (
present(cmor_field_name))
then 1542 posted_cmor_units =
"not provided" 1543 posted_cmor_standard_name =
"not provided" 1544 posted_cmor_long_name =
"not provided" 1548 if (
present(units)) posted_cmor_units = units
1549 if (
present(standard_name)) posted_cmor_standard_name = standard_name
1550 if (
present(long_name)) posted_cmor_long_name = long_name
1553 if (
present(cmor_units)) posted_cmor_units = cmor_units
1554 if (
present(cmor_standard_name)) posted_cmor_standard_name = cmor_standard_name
1555 if (
present(cmor_long_name)) posted_cmor_long_name = cmor_long_name
1558 long_name=trim(posted_cmor_long_name), units=trim(posted_cmor_units), &
1559 missing_value=mom_missing_value, range=range, &
1560 standard_name=trim(posted_cmor_standard_name), do_not_log=do_not_log, err_msg=err_msg)
1561 if (fms_id /= diag_field_not_found)
then 1562 if (dm_id == -1)
then 1566 cmor_diag%fms_diag_id = fms_id
1567 cmor_diag%debug_str = trim(module_name)//
"-"//trim(cmor_field_name)
1572 if (
is_root_pe() .and. diag_cs%doc_unit > 0)
then 1573 call log_available_diag(
associated(diag), module_name, field_name,
'',
'', diag_cs, &
1574 long_name, units, standard_name)
1575 if (
present(cmor_field_name))
then 1577 '',
'', diag_cs, posted_cmor_long_name, posted_cmor_units, &
1578 posted_cmor_standard_name)
1582 register_scalar_field = dm_id
1588 long_name, units, missing_value, range, mask_variant, standard_name, &
1589 do_not_log, interp_method, tile_count, &
1590 cmor_field_name, cmor_long_name, cmor_units, cmor_standard_name, area)
1591 integer :: register_static_field
1592 character(len=*),
intent(in) :: module_name, field_name
1594 character(len=*),
optional,
intent(in) :: long_name, units, standard_name
1595 real,
optional,
intent(in) :: missing_value, range(2)
1596 logical,
optional,
intent(in) :: mask_variant, do_not_log
1597 character(len=*),
optional,
intent(in) :: interp_method
1598 integer,
optional,
intent(in) :: tile_count
1599 character(len=*),
optional,
intent(in) :: cmor_field_name, cmor_long_name
1600 character(len=*),
optional,
intent(in) :: cmor_units, cmor_standard_name
1601 integer,
optional,
intent(in) :: area
1620 real :: MOM_missing_value
1622 type(
diag_type),
pointer :: diag => null(), cmor_diag => null()
1623 integer :: dm_id, fms_id, cmor_id
1624 character(len=256) :: posted_cmor_units, posted_cmor_standard_name, posted_cmor_long_name
1626 mom_missing_value = axes%diag_cs%missing_value
1627 if(
present(missing_value)) mom_missing_value = missing_value
1629 diag_cs => axes%diag_cs
1634 fms_id = register_static_field_fms(module_name, field_name, axes%handles, &
1635 long_name=long_name, units=units, missing_value=mom_missing_value, &
1636 range=range, mask_variant=mask_variant, standard_name=standard_name, &
1637 do_not_log=do_not_log, &
1638 interp_method=interp_method, tile_count=tile_count, area=area)
1639 if (fms_id /= diag_field_not_found)
then 1642 call assert(
associated(diag),
'register_static_field: diag allocation failed')
1643 diag%fms_diag_id = fms_id
1644 diag%debug_str = trim(module_name)//
"-"//trim(field_name)
1647 if (
present(cmor_field_name))
then 1649 posted_cmor_units =
"not provided" 1650 posted_cmor_standard_name =
"not provided" 1651 posted_cmor_long_name =
"not provided" 1655 if (
present(units)) posted_cmor_units = units
1656 if (
present(standard_name)) posted_cmor_standard_name = standard_name
1657 if (
present(long_name)) posted_cmor_long_name = long_name
1660 if (
present(cmor_units)) posted_cmor_units = cmor_units
1661 if (
present(cmor_standard_name)) posted_cmor_standard_name = cmor_standard_name
1662 if (
present(cmor_long_name)) posted_cmor_long_name = cmor_long_name
1664 fms_id = register_static_field_fms(module_name, cmor_field_name, &
1665 axes%handles, long_name=trim(posted_cmor_long_name), units=trim(posted_cmor_units), &
1666 missing_value=mom_missing_value, range=range, mask_variant=mask_variant, &
1667 standard_name=trim(posted_cmor_standard_name), do_not_log=do_not_log, &
1668 interp_method=interp_method, tile_count=tile_count, area=area)
1669 if (fms_id /= diag_field_not_found)
then 1670 if (dm_id == -1)
then 1674 cmor_diag%fms_diag_id = fms_id
1675 cmor_diag%debug_str = trim(module_name)//
"-"//trim(cmor_field_name)
1680 if (
is_root_pe() .and. diag_cs%doc_unit > 0)
then 1681 call log_available_diag(
associated(diag), module_name, field_name,
'',
'', diag_cs, &
1682 long_name, units, standard_name)
1683 if (
present(cmor_field_name))
then 1685 '',
'', diag_cs, posted_cmor_long_name, posted_cmor_units, &
1686 posted_cmor_standard_name)
1690 register_static_field = dm_id
1695 character(len=*),
intent(in) :: opt_name, value
1698 character(len=240) :: mesg
1701 len_ind = len_trim(
value)
1703 mesg =
" ! "//trim(opt_name)//
": "//trim(
value)
1704 write(diag_cs%doc_unit,
'(a)') trim(mesg)
1711 integer :: ocean_register_diag
1712 type(
vardesc),
intent(in) :: var_desc
1714 type(
diag_ctrl),
intent(in),
target :: diag_CS
1715 type(time_type),
intent(in) :: day
1717 character(len=64) :: var_name
1718 character(len=48) :: units
1719 character(len=240) :: longname
1720 character(len=8) :: hor_grid, z_grid
1723 call query_vardesc(var_desc, units=units, longname=longname, hor_grid=hor_grid, &
1724 z_grid=z_grid, caller=
"ocean_register_diag")
1728 select case (z_grid)
1731 select case (hor_grid)
1733 axes => diag_cs%axesBL
1735 axes => diag_cs%axesTL
1737 axes => diag_cs%axesCuL
1739 axes => diag_cs%axesCvL
1741 axes => diag_cs%axesBL
1743 axes => diag_cs%axesTL
1745 axes => diag_cs%axesCuL
1747 axes => diag_cs%axesCvL
1749 axes => diag_cs%axeszL
1751 call mom_error(fatal,
"ocean_register_diag: " // &
1752 "unknown hor_grid component "//trim(hor_grid))
1756 select case (hor_grid)
1758 axes => diag_cs%axesBi
1760 axes => diag_cs%axesTi
1762 axes => diag_cs%axesCui
1764 axes => diag_cs%axesCvi
1766 axes => diag_cs%axesBi
1768 axes => diag_cs%axesTi
1770 axes => diag_cs%axesCui
1772 axes => diag_cs%axesCvi
1774 axes => diag_cs%axeszi
1776 call mom_error(fatal,
"ocean_register_diag: " // &
1777 "unknown hor_grid component "//trim(hor_grid))
1781 select case (hor_grid)
1783 axes => diag_cs%axesB1
1785 axes => diag_cs%axesT1
1787 axes => diag_cs%axesCu1
1789 axes => diag_cs%axesCv1
1791 axes => diag_cs%axesB1
1793 axes => diag_cs%axesT1
1795 axes => diag_cs%axesCu1
1797 axes => diag_cs%axesCv1
1799 call mom_error(fatal,
"ocean_register_diag: " // &
1800 "unknown hor_grid component "//trim(hor_grid))
1805 "ocean_register_diag: unknown z_grid component "//trim(z_grid))
1809 axes, day, trim(longname), trim(units), missing_value = -1.0e+34)
1815 character(len=*),
optional,
intent(out) :: err_msg
1817 call diag_manager_init(err_msg=err_msg)
1824 integer,
intent(in) :: nz
1826 type(
diag_ctrl),
intent(inout) :: diag_cs
1828 character(len=*),
optional,
intent(in) :: doc_file_dir
1834 integer :: ios, i, new_unit
1835 logical :: opened, new_file
1836 character(len=8) :: this_pe
1837 character(len=240) :: doc_file, doc_file_dflt, doc_path
1838 character(len=240),
allocatable :: diag_coords(:)
1840 #include "version_variable.h" 1841 character(len=40) :: mod =
"MOM_diag_mediator" 1848 allocate(diag_cs%diags(diag_alloc_chunk_size))
1849 diag_cs%next_free_diag_id = 1
1850 do i=1, diag_alloc_chunk_size
1857 call get_param(param_file, mod,
'NUM_DIAG_COORDS', diag_cs%num_diag_coords, &
1858 'The number of diagnostic vertical coordinates to use.\n'//&
1859 'For each coordinate, an entry in DIAG_COORDS must be provided.', &
1861 if (diag_cs%num_diag_coords>0)
then 1862 allocate(diag_coords(diag_cs%num_diag_coords))
1863 if (diag_cs%num_diag_coords==1)
then 1864 call get_param(param_file, mod,
'DIAG_COORDS', diag_coords, &
1865 'A list of string tuples associating diag_table modules to\n'//&
1866 'a coordinate definition used for diagnostics. Each string\n'//&
1867 'is of the form "MODULE_SUFFIX PARAMETER_SUFFIX COORDINATE_NAME".', &
1868 default=
'z Z ZSTAR')
1870 call get_param(param_file, mod,
'DIAG_COORDS', diag_coords, &
1871 'A list of string tuples associating diag_table modules to\n'//&
1872 'a coordinate definition used for diagnostics. Each string\n'//&
1873 'is of the form "MODULE_SUFFIX,PARAMETER_SUFFIX,COORDINATE_NAME".', &
1874 fail_if_missing=.true.)
1876 allocate(diag_cs%diag_remap_cs(diag_cs%num_diag_coords))
1878 do i=1, diag_cs%num_diag_coords
1879 call diag_remap_init(diag_cs%diag_remap_cs(i), diag_coords(i))
1881 deallocate(diag_coords)
1884 call get_param(param_file, mod,
'DIAG_MISVAL', diag_cs%missing_value, &
1885 'Set the default missing value to use for diagnostics.', &
1893 diag_cs%eqn_of_state => null()
1895 #if defined(DEBUG) || defined(__DO_SAFETY_CHECKS__) 1896 allocate(diag_cs%h_old(g%isd:g%ied,g%jsd:g%jed,nz))
1897 diag_cs%h_old(:,:,:) = 0.0
1900 diag_cs%is = g%isc - (g%isd-1) ; diag_cs%ie = g%iec - (g%isd-1)
1901 diag_cs%js = g%jsc - (g%jsd-1) ; diag_cs%je = g%jec - (g%jsd-1)
1902 diag_cs%isd = g%isd ; diag_cs%ied = g%ied
1903 diag_cs%jsd = g%jsd ; diag_cs%jed = g%jed
1905 if (
is_root_pe() .and. (diag_cs%doc_unit < 0))
then 1906 write(this_pe,
'(i6.6)') pe_here()
1907 doc_file_dflt =
"available_diags."//this_pe
1908 call get_param(param_file, mod,
"AVAILABLE_DIAGS_FILE", doc_file, &
1909 "A file into which to write a list of all available \n"//&
1910 "ocean diagnostics that can be included in a diag_table.", &
1911 default=doc_file_dflt, do_not_log=(diag_cs%doc_unit/=-1))
1912 if (len_trim(doc_file) > 0)
then 1913 new_file = .true. ;
if (diag_cs%doc_unit /= -1) new_file = .false.
1915 do new_unit=512,42,-1
1916 inquire( new_unit, opened=opened)
1917 if (.not.opened)
exit 1920 "diag_mediator_init failed to find an unused unit number.")
1923 if (
present(doc_file_dir))
then ;
if (len_trim(doc_file_dir) > 0)
then 1924 doc_path = trim(slasher(doc_file_dir))//trim(doc_file)
1927 diag_cs%doc_unit = new_unit
1930 open(diag_cs%doc_unit, file=trim(doc_path), access=
'SEQUENTIAL', form=
'FORMATTED', &
1931 action=
'WRITE', status=
'REPLACE', iostat=ios)
1933 open(diag_cs%doc_unit, file=trim(doc_path), access=
'SEQUENTIAL', form=
'FORMATTED', &
1934 action=
'WRITE', status=
'OLD', position=
'APPEND', iostat=ios)
1936 inquire(diag_cs%doc_unit, opened=opened)
1937 if ((.not.opened) .or. (ios /= 0))
then 1938 call mom_error(fatal,
"Failed to open available diags file "//trim(doc_path)//
".")
1947 real,
dimension(:,:,:),
target,
intent(in) :: h, T, S
1948 type(
eos_type),
pointer,
intent(in) :: eqn_of_state
1949 type(
diag_ctrl),
intent(inout) :: diag_cs
1960 diag_cs%eqn_of_state => eqn_of_state
1969 real,
target,
optional,
intent(in ) :: alt_h(:,:,:)
1974 real,
dimension(:,:,:),
pointer :: h_diag
1976 if(
present(alt_h))
then 1984 do i=1, diag_cs%num_diag_coords
1985 call diag_remap_update(diag_cs%diag_remap_cs(i), &
1986 diag_cs%G, h_diag, diag_cs%T, diag_cs%S, &
1987 diag_cs%eqn_of_state)
1990 #if defined(DEBUG) || defined(__DO_SAFETY_CHECKS__) 1993 diag_cs%h_old(:,:,:) = diag_cs%h(:,:,:)
2003 integer,
intent(in) :: nz
2004 real,
intent(in) :: missing_value
2010 diag_cs%mask2dT => g%mask2dT
2011 diag_cs%mask2dBu=> g%mask2dBu
2012 diag_cs%mask2dCu=> g%mask2dCu
2013 diag_cs%mask2dCv=> g%mask2dCv
2014 allocate(diag_cs%mask3dTL(g%isd:g%ied,g%jsd:g%jed,1:nz))
2015 allocate(diag_cs%mask3dBL(g%IsdB:g%IedB,g%JsdB:g%JedB,1:nz))
2016 allocate(diag_cs%mask3dCuL(g%IsdB:g%IedB,g%jsd:g%jed,1:nz))
2017 allocate(diag_cs%mask3dCvL(g%isd:g%ied,g%JsdB:g%JedB,1:nz))
2019 diag_cs%mask3dTL(:,:,k) = diag_cs%mask2dT (:,:)
2020 diag_cs%mask3dBL(:,:,k) = diag_cs%mask2dBu(:,:)
2021 diag_cs%mask3dCuL(:,:,k) = diag_cs%mask2dCu(:,:)
2022 diag_cs%mask3dCvL(:,:,k) = diag_cs%mask2dCv(:,:)
2024 allocate(diag_cs%mask3dTi(g%isd:g%ied,g%jsd:g%jed,1:nz+1))
2025 allocate(diag_cs%mask3dBi(g%IsdB:g%IedB,g%JsdB:g%JedB,1:nz+1))
2026 allocate(diag_cs%mask3dCui(g%IsdB:g%IedB,g%jsd:g%jed,1:nz+1))
2027 allocate(diag_cs%mask3dCvi(g%isd:g%ied,g%JsdB:g%JedB,1:nz+1))
2029 diag_cs%mask3dTi(:,:,k) = diag_cs%mask2dT (:,:)
2030 diag_cs%mask3dBi(:,:,k) = diag_cs%mask2dBu(:,:)
2031 diag_cs%mask3dCui(:,:,k) = diag_cs%mask2dCu(:,:)
2032 diag_cs%mask3dCvi(:,:,k) = diag_cs%mask2dCv(:,:)
2044 if (diag_cs%doc_unit > -1)
then 2045 close(diag_cs%doc_unit) ; diag_cs%doc_unit = -2
2048 do i=1, diag_cs%num_diag_coords
2049 call diag_remap_diag_registration_closed(diag_cs%diag_remap_cs(i))
2055 type(time_type),
intent(in) :: time
2056 type(
diag_ctrl),
intent(inout) :: diag_cs
2057 logical,
optional,
intent(in) :: end_diag_manager
2062 if (diag_cs%doc_unit > -1)
then 2063 close(diag_cs%doc_unit) ; diag_cs%doc_unit = -3
2066 deallocate(diag_cs%diags)
2068 do i=1, diag_cs%num_diag_coords
2069 call diag_remap_end(diag_cs%diag_remap_cs(i))
2072 deallocate(diag_cs%mask3dTL)
2073 deallocate(diag_cs%mask3dBL)
2074 deallocate(diag_cs%mask3dCuL)
2075 deallocate(diag_cs%mask3dCvL)
2076 deallocate(diag_cs%mask3dTi)
2077 deallocate(diag_cs%mask3dBi)
2078 deallocate(diag_cs%mask3dCui)
2079 deallocate(diag_cs%mask3dCvi)
2081 #if defined(DEBUG) || defined(__DO_SAFETY_CHECKS__) 2082 deallocate(diag_cs%h_old)
2085 if (
present(end_diag_manager))
then 2086 if (end_diag_manager)
call diag_manager_end(time)
2091 function i2s(a,n_in)
2093 integer,
dimension(:),
intent(in) :: a
2094 integer,
optional ,
intent(in) :: n_in
2095 character(len=15) :: i2s
2097 character(len=15) :: i2s_temp
2101 if(
present(n_in)) n = n_in
2105 write (i2s_temp,
'(I4.4)') a(i)
2106 i2s = trim(i2s) //
'_'// trim(i2s_temp)
2114 type(
diag_type),
pointer,
intent(inout) :: diag
2117 diag%mask2d => null()
2118 diag%mask3d => null()
2120 if (axes%rank .eq. 3)
then 2121 if (axes%is_layer)
then 2122 if (axes%is_h_point)
then 2123 diag%mask3d => diag_cs%mask3dTL
2124 elseif (axes%is_q_point)
then 2125 diag%mask3d => diag_cs%mask3dBL
2126 elseif (axes%is_u_point)
then 2127 diag%mask3d => diag_cs%mask3dCuL
2128 elseif (axes%is_v_point)
then 2129 diag%mask3d => diag_cs%mask3dCvL
2131 elseif (axes%is_interface)
then 2132 if (axes%is_h_point)
then 2133 diag%mask3d => diag_cs%mask3dTi
2134 elseif (axes%is_q_point)
then 2135 diag%mask3d => diag_cs%mask3dBi
2136 elseif (axes%is_u_point)
then 2137 diag%mask3d => diag_cs%mask3dCui
2138 elseif (axes%is_v_point)
then 2139 diag%mask3d => diag_cs%mask3dCvi
2145 elseif(axes%rank .eq. 2)
then 2147 if (axes%is_h_point)
then 2148 diag%mask2d => diag_cs%mask2dT
2149 elseif (axes%is_q_point)
then 2150 diag%mask2d => diag_cs%mask2dBu
2151 elseif (axes%is_u_point)
then 2152 diag%mask2d => diag_cs%mask2dCu
2153 elseif (axes%is_v_point)
then 2154 diag%mask2d => diag_cs%mask2dCv
2167 type(
diag_type),
dimension(:),
allocatable :: tmp
2170 if (diag_cs%next_free_diag_id >
size(diag_cs%diags))
then 2171 call assert(diag_cs%next_free_diag_id -
size(diag_cs%diags) == 1, &
2172 'get_new_diag_id: inconsistent diag id')
2176 allocate(tmp(
size(diag_cs%diags)))
2177 tmp(:) = diag_cs%diags(:)
2178 deallocate(diag_cs%diags)
2179 allocate(diag_cs%diags(
size(tmp) + diag_alloc_chunk_size))
2180 diag_cs%diags(1:
size(tmp)) = tmp(:)
2184 do i=diag_cs%next_free_diag_id,
size(diag_cs%diags)
2190 diag_cs%next_free_diag_id = diag_cs%next_free_diag_id + 1
2198 diag%in_use = .false.
2199 diag%fms_diag_id = -1
2201 diag%mask2d => null()
2202 diag%mask3d => null()
2204 diag%conversion_factor = 0.
2211 integer,
intent(in) :: diag_id
2212 type(
diag_ctrl),
target,
intent(inout) :: diag_cs
2213 type(
diag_type),
pointer,
intent(out) :: diag
2222 if (.not. diag_cs%diags(diag_id)%in_use)
then 2223 diag => diag_cs%diags(diag_id)
2226 tmp => diag_cs%diags(diag_id)%next
2227 diag_cs%diags(diag_id)%next => diag
2230 diag%in_use = .true.
2235 subroutine log_available_diag(used, module_name, field_name, cell_methods_string, comment, &
2236 diag_CS, long_name, units, standard_name)
2237 logical,
intent(in) :: used
2238 character(len=*),
intent(in) :: module_name
2239 character(len=*),
intent(in) :: field_name
2240 character(len=*),
intent(in) :: cell_methods_string
2241 character(len=*),
intent(in) :: comment
2243 character(len=*),
optional,
intent(in) :: long_name
2244 character(len=*),
optional,
intent(in) :: units
2245 character(len=*),
optional,
intent(in) :: standard_name
2247 character(len=240) :: mesg
2250 mesg =
'"'//trim(module_name)//
'", "'//trim(field_name)//
'" [Used]' 2252 mesg =
'"'//trim(module_name)//
'", "'//trim(field_name)//
'" [Unused]' 2254 if (len(trim((comment)))>0)
then 2255 write(diag_cs%doc_unit,
'(a,x,"(",a,")")') trim(mesg),trim(comment)
2257 write(diag_cs%doc_unit,
'(a)') trim(mesg)
2259 if (
present(long_name))
call describe_option(
"long_name", long_name, diag_cs)
2261 if (
present(standard_name)) &
2263 if (len(trim((cell_methods_string)))>0) &
2264 call describe_option(
"cell_methods", trim(cell_methods_string), diag_cs)
subroutine, public diag_remap_set_active(remap_cs)
Indicate that this remapping type is actually used by the diag manager. If this is never called then ...
subroutine, public diag_remap_init(remap_cs, coord_tuple)
Initialize a diagnostic remapping type with the given vertical coordinate.
Ocean grid type. See mom_grid for details.
logical function, public diag_remap_axes_configured(remap_cs)
Whether or not the axes for this vertical coordinated has been configured. Configuration is complete ...
subroutine, public diag_remap_diag_registration_closed(remap_cs)
Inform that all diagnostics have been registered. If _set_active() has not been called on the remappi...
Provides the ocean grid type.
subroutine, public diag_remap_end(remap_cs)
De-init a diagnostic remapping type. Free allocated memory.
subroutine, public vertically_interpolate_diag_field(remap_cs, G, h, staggered_in_x, staggered_in_y, mask, missing_value, field, interpolated_field)
Vertically interpolate diagnostic field to alternative vertical grid.
A simple (very thin) wrapper for register_diag_field to avoid a compiler bug with PGI...
This module contains I/O framework code.
subroutine, public diag_remap_get_axes_info(remap_cs, nz, id_layer, id_interface)
Get layer and interface axes ids for this coordinate Needed when defining axes groups.
character(len=len(input_string)) function, public lowercase(input_string)
A wrapper for register_diag_field_array()
This type represents remapping of diagnostics to a particular vertical coordinate. There is one of these types for each vertical coordinate. The vertical axes of a diagnostic will reference an instance of this type indicating how (or if) the diagnostic should be vertically remapped when being posted.
logical function, public is_root_pe()
subroutine, public assert(logical_arg, msg)
Issues a FATAL error if the assertion fails, i.e. the first argument is false.
subroutine, public diag_remap_update(remap_cs, G, h, T, S, eqn_of_state)
Build/update target vertical grids for diagnostic remapping.
subroutine, public horizontally_average_diag_field(G, h, staggered_in_x, staggered_in_y, is_layer, is_extensive, missing_value, field, averaged_field)
Horizontally average field.
This module is used for runtime remapping of diagnostics to z star, sigma and rho vertical coordinate...
Provides subroutines for quantities specific to the equation of state.
Type for describing a variable, typically a tracer.
subroutine, public diag_remap_do_remap(remap_cs, G, h, staggered_in_x, staggered_in_y, mask, missing_value, field, remapped_field)
Remap diagnostic field to alternative vertical grid.
subroutine, public vertically_reintegrate_diag_field(remap_cs, G, h, staggered_in_x, staggered_in_y, mask, missing_value, field, reintegrated_field)
Vertically re-grid an already vertically-integrated diagnostic field to alternative vertical grid...
subroutine, public query_vardesc(vd, name, units, longname, hor_grid, z_grid, t_grid, cmor_field_name, cmor_units, conversion, caller)
This routine queries vardesc.
subroutine, public mom_error(level, message, all_print)
subroutine, public diag_remap_configure_axes(remap_cs, GV, param_file)
Configure the vertical axes for a diagnostic remapping control structure. Reads a configuration param...
A control structure for the equation of state.