10 use mom_cpu_clock,
only : cpu_clock_id, cpu_clock_begin, cpu_clock_end
16 use mom_io,
only : get_filename_appendix
33 use diag_axis_mod,
only : get_diag_axis_name
34 use diag_data_mod,
only : null_axis_id
35 use diag_manager_mod,
only : diag_manager_init, diag_manager_end
36 use diag_manager_mod,
only : send_data, diag_axis_init, diag_field_add_attribute
41 use diag_manager_mod,
only : get_diag_field_id_fms=>get_diag_field_id
42 use diag_manager_mod,
only : diag_field_not_found
44 implicit none ;
private
46 #undef __DO_SAFETY_CHECKS__
47 #define IMPLIES(A, B) ((.not. (A)) .or. (B))
48 #define MAX_DSAMP_LEV 2
91 real,
pointer,
dimension(:,:) :: mask2d => null()
92 real,
pointer,
dimension(:,:,:) :: mask3d => null()
97 character(len=15) :: id
99 integer,
dimension(:),
allocatable :: handles
103 character(len=9) :: x_cell_method =
''
105 character(len=9) :: y_cell_method =
''
107 character(len=9) :: v_cell_method =
''
111 integer :: vertical_coordinate_number = 0
113 logical :: is_h_point = .false.
114 logical :: is_q_point = .false.
115 logical :: is_u_point = .false.
116 logical :: is_v_point = .false.
117 logical :: is_layer = .false.
118 logical :: is_interface = .false.
120 logical :: is_native = .true.
122 logical :: needs_remapping = .false.
124 logical :: needs_interpolating = .false.
127 integer :: downsample_level = 1
131 integer :: id_area = -1
132 integer :: id_volume = -1
135 real,
pointer,
dimension(:,:) :: mask2d => null()
136 real,
pointer,
dimension(:,:,:) :: mask3d => null()
142 real,
dimension(:,:,:),
allocatable :: h
147 integer :: num_diag_coords
148 real,
dimension(:,:,:),
allocatable :: h_state
181 integer :: fms_diag_id
182 integer :: fms_xyave_diag_id = -1
183 integer :: downsample_diag_id = -1
184 character(64) :: debug_str =
''
187 real :: conversion_factor = 0.
188 logical :: v_extensive = .false.
190 integer :: xyz_method = 0
217 type(
axes_grp),
dimension(:),
allocatable :: remap_axestl, remap_axesbl, remap_axescul, remap_axescvl
218 type(
axes_grp),
dimension(:),
allocatable :: remap_axesti, remap_axesbi, remap_axescui, remap_axescvi
221 real,
dimension(:,:),
pointer :: mask2dt => null()
222 real,
dimension(:,:),
pointer :: mask2dbu => null()
223 real,
dimension(:,:),
pointer :: mask2dcu => null()
224 real,
dimension(:,:),
pointer :: mask2dcv => null()
226 real,
dimension(:,:,:),
pointer :: mask3dtl => null()
227 real,
dimension(:,:,:),
pointer :: mask3dbl => null()
228 real,
dimension(:,:,:),
pointer :: mask3dcul => null()
229 real,
dimension(:,:,:),
pointer :: mask3dcvl => null()
230 real,
dimension(:,:,:),
pointer :: mask3dti => null()
231 real,
dimension(:,:,:),
pointer :: mask3dbi => null()
232 real,
dimension(:,:,:),
pointer :: mask3dcui => null()
233 real,
dimension(:,:,:),
pointer :: mask3dcvi => null()
240 integer :: available_diag_doc_unit = -1
242 integer :: chksum_iounit = -1
244 logical :: diag_as_chksum
258 type(time_type) :: time_end
260 logical :: ave_enabled = .false.
272 real,
dimension(:,:),
pointer :: mask2dt => null()
273 real,
dimension(:,:),
pointer :: mask2dbu => null()
274 real,
dimension(:,:),
pointer :: mask2dcu => null()
275 real,
dimension(:,:),
pointer :: mask2dcv => null()
277 real,
dimension(:,:,:),
pointer :: mask3dtl => null()
278 real,
dimension(:,:,:),
pointer :: mask3dbl => null()
279 real,
dimension(:,:,:),
pointer :: mask3dcul => null()
280 real,
dimension(:,:,:),
pointer :: mask3dcvl => null()
281 real,
dimension(:,:,:),
pointer :: mask3dti => null()
282 real,
dimension(:,:,:),
pointer :: mask3dbi => null()
283 real,
dimension(:,:,:),
pointer :: mask3dcui => null()
284 real,
dimension(:,:,:),
pointer :: mask3dcvi => null()
292 #define DIAG_ALLOC_CHUNK_SIZE 100
294 integer :: next_free_diag_id
297 real :: missing_value = -1.0e+34
300 integer :: num_diag_coords
304 logical :: diag_grid_overridden = .false.
307 remap_axeszl, & !< The 1-D z-space cell-centered axis for remapping
310 type(
axes_grp),
dimension(:),
allocatable :: remap_axestl, remap_axesbl, remap_axescul, remap_axescvl
311 type(
axes_grp),
dimension(:),
allocatable :: remap_axesti, remap_axesbi, remap_axescui, remap_axescvi
315 real,
dimension(:,:,:),
pointer :: h => null()
316 real,
dimension(:,:,:),
pointer :: t => null()
317 real,
dimension(:,:,:),
pointer :: s => null()
324 integer :: volume_cell_measure_dm_id = -1
326 #if defined(DEBUG) || defined(__DO_SAFETY_CHECKS__)
329 real,
dimension(:,:,:),
allocatable :: h_old
333 integer :: num_chksum_diags
343 subroutine set_axes_info(G, GV, US, param_file, diag_cs, set_vertical)
348 type(
diag_ctrl),
intent(inout) :: diag_cs
349 logical,
optional,
intent(in) :: set_vertical
352 integer :: id_xq, id_yq, id_zl, id_zi, id_xh, id_yh
353 integer :: id_zl_native, id_zi_native
354 integer :: i, j, k, nz
355 real :: zlev(gv%ke), zinter(gv%ke+1)
358 set_vert = .true. ;
if (
present(set_vertical)) set_vert = set_vertical
361 if (g%symmetric)
then
362 id_xq = diag_axis_init(
'xq', g%gridLonB(g%isgB:g%iegB), g%x_axis_units,
'x', &
363 'q point nominal longitude', domain2=g%Domain%mpp_domain)
364 id_yq = diag_axis_init(
'yq', g%gridLatB(g%jsgB:g%jegB), g%y_axis_units,
'y', &
365 'q point nominal latitude', domain2=g%Domain%mpp_domain)
367 id_xq = diag_axis_init(
'xq', g%gridLonB(g%isg:g%ieg), g%x_axis_units,
'x', &
368 'q point nominal longitude', domain2=g%Domain%mpp_domain)
369 id_yq = diag_axis_init(
'yq', g%gridLatB(g%jsg:g%jeg), g%y_axis_units,
'y', &
370 'q point nominal latitude', domain2=g%Domain%mpp_domain)
372 id_xh = diag_axis_init(
'xh', g%gridLonT(g%isg:g%ieg), g%x_axis_units,
'x', &
373 'h point nominal longitude', domain2=g%Domain%mpp_domain)
374 id_yh = diag_axis_init(
'yh', g%gridLatT(g%jsg:g%jeg), g%y_axis_units,
'y', &
375 'h point nominal latitude', domain2=g%Domain%mpp_domain)
379 zinter(1:nz+1) = gv%sInterface(1:nz+1)
380 zlev(1:nz) = gv%sLayer(1:nz)
381 id_zl = diag_axis_init(
'zl', zlev, trim(gv%zAxisUnits),
'z', &
382 'Layer '//trim(gv%zAxisLongName), &
383 direction=gv%direction)
384 id_zi = diag_axis_init(
'zi', zinter, trim(gv%zAxisUnits),
'z', &
385 'Interface '//trim(gv%zAxisLongName), &
386 direction=gv%direction)
388 id_zl = -1 ; id_zi = -1
390 id_zl_native = id_zl ; id_zi_native = id_zi
393 v_cell_method=
'point', is_interface=.true.)
395 v_cell_method=
'mean', is_layer=.true.)
399 x_cell_method=
'mean', y_cell_method=
'mean', v_cell_method=
'mean', &
400 is_h_point=.true., is_layer=.true., xyave_axes=diag_cs%axesZL)
402 x_cell_method=
'point', y_cell_method=
'point', v_cell_method=
'mean', &
403 is_q_point=.true., is_layer=.true.)
405 x_cell_method=
'point', y_cell_method=
'mean', v_cell_method=
'mean', &
406 is_u_point=.true., is_layer=.true., xyave_axes=diag_cs%axesZL)
408 x_cell_method=
'mean', y_cell_method=
'point', v_cell_method=
'mean', &
409 is_v_point=.true., is_layer=.true., xyave_axes=diag_cs%axesZL)
413 x_cell_method=
'mean', y_cell_method=
'mean', v_cell_method=
'point', &
414 is_h_point=.true., is_interface=.true., xyave_axes=diag_cs%axesZi)
416 x_cell_method=
'point', y_cell_method=
'point', v_cell_method=
'point', &
417 is_q_point=.true., is_interface=.true.)
419 x_cell_method=
'point', y_cell_method=
'mean', v_cell_method=
'point', &
420 is_u_point=.true., is_interface=.true., xyave_axes=diag_cs%axesZi)
422 x_cell_method=
'mean', y_cell_method=
'point', v_cell_method=
'point', &
423 is_v_point=.true., is_interface=.true., xyave_axes=diag_cs%axesZi)
427 x_cell_method=
'mean', y_cell_method=
'mean', is_h_point=.true.)
429 x_cell_method=
'point', y_cell_method=
'point', is_q_point=.true.)
431 x_cell_method=
'point', y_cell_method=
'mean', is_u_point=.true.)
433 x_cell_method=
'mean', y_cell_method=
'point', is_v_point=.true.)
440 if (diag_cs%num_diag_coords>0)
then
441 allocate(diag_cs%remap_axesZL(diag_cs%num_diag_coords))
442 allocate(diag_cs%remap_axesTL(diag_cs%num_diag_coords))
443 allocate(diag_cs%remap_axesBL(diag_cs%num_diag_coords))
444 allocate(diag_cs%remap_axesCuL(diag_cs%num_diag_coords))
445 allocate(diag_cs%remap_axesCvL(diag_cs%num_diag_coords))
446 allocate(diag_cs%remap_axesZi(diag_cs%num_diag_coords))
447 allocate(diag_cs%remap_axesTi(diag_cs%num_diag_coords))
448 allocate(diag_cs%remap_axesBi(diag_cs%num_diag_coords))
449 allocate(diag_cs%remap_axesCui(diag_cs%num_diag_coords))
450 allocate(diag_cs%remap_axesCvi(diag_cs%num_diag_coords))
453 do i=1, diag_cs%num_diag_coords
455 call diag_remap_configure_axes(diag_cs%diag_remap_cs(i), gv, us, param_file)
458 if (diag_remap_axes_configured(diag_cs%diag_remap_cs(i)))
then
462 call diag_remap_get_axes_info(diag_cs%diag_remap_cs(i), nz, id_zl, id_zi)
466 nz=nz, vertical_coordinate_number=i, &
467 v_cell_method=
'mean', &
468 is_h_point=.true., is_layer=.true., is_native=.false., needs_remapping=.true.)
469 call define_axes_group(diag_cs, (/ id_xh, id_yh, id_zl /), diag_cs%remap_axesTL(i), &
470 nz=nz, vertical_coordinate_number=i, &
471 x_cell_method=
'mean', y_cell_method=
'mean', v_cell_method=
'mean', &
472 is_h_point=.true., is_layer=.true., is_native=.false., needs_remapping=.true., &
473 xyave_axes=diag_cs%remap_axesZL(i))
477 call define_axes_group(diag_cs, (/ id_xq, id_yq, id_zl /), diag_cs%remap_axesBL(i), &
478 nz=nz, vertical_coordinate_number=i, &
479 x_cell_method=
'point', y_cell_method=
'point', v_cell_method=
'mean', &
480 is_q_point=.true., is_layer=.true., is_native=.false.)
482 call define_axes_group(diag_cs, (/ id_xq, id_yh, id_zl /), diag_cs%remap_axesCuL(i), &
483 nz=nz, vertical_coordinate_number=i, &
484 x_cell_method=
'point', y_cell_method=
'mean', v_cell_method=
'mean', &
485 is_u_point=.true., is_layer=.true., is_native=.false., needs_remapping=.true., &
486 xyave_axes=diag_cs%remap_axesZL(i))
488 call define_axes_group(diag_cs, (/ id_xh, id_yq, id_zl /), diag_cs%remap_axesCvL(i), &
489 nz=nz, vertical_coordinate_number=i, &
490 x_cell_method=
'mean', y_cell_method=
'point', v_cell_method=
'mean', &
491 is_v_point=.true., is_layer=.true., is_native=.false., needs_remapping=.true., &
492 xyave_axes=diag_cs%remap_axesZL(i))
496 nz=nz, vertical_coordinate_number=i, &
497 v_cell_method=
'point', &
498 is_h_point=.true., is_interface=.true., is_native=.false., needs_interpolating=.true.)
499 call define_axes_group(diag_cs, (/ id_xh, id_yh, id_zi /), diag_cs%remap_axesTi(i), &
500 nz=nz, vertical_coordinate_number=i, &
501 x_cell_method=
'mean', y_cell_method=
'mean', v_cell_method=
'point', &
502 is_h_point=.true., is_interface=.true., is_native=.false., needs_interpolating=.true., &
503 xyave_axes=diag_cs%remap_axesZi(i))
506 call define_axes_group(diag_cs, (/ id_xq, id_yq, id_zi /), diag_cs%remap_axesBi(i), &
507 nz=nz, vertical_coordinate_number=i, &
508 x_cell_method=
'point', y_cell_method=
'point', v_cell_method=
'point', &
509 is_q_point=.true., is_interface=.true., is_native=.false.)
511 call define_axes_group(diag_cs, (/ id_xq, id_yh, id_zi /), diag_cs%remap_axesCui(i), &
512 nz=nz, vertical_coordinate_number=i, &
513 x_cell_method=
'point', y_cell_method=
'mean', v_cell_method=
'point', &
514 is_u_point=.true., is_interface=.true., is_native=.false., &
515 needs_interpolating=.true., xyave_axes=diag_cs%remap_axesZi(i))
517 call define_axes_group(diag_cs, (/ id_xh, id_yq, id_zi /), diag_cs%remap_axesCvi(i), &
518 nz=nz, vertical_coordinate_number=i, &
519 x_cell_method=
'mean', y_cell_method=
'point', v_cell_method=
'point', &
520 is_v_point=.true., is_interface=.true., is_native=.false., &
521 needs_interpolating=.true., xyave_axes=diag_cs%remap_axesZi(i))
536 type(
diag_ctrl),
intent(inout) :: diag_cs
537 integer,
intent(in) :: id_zl_native
538 integer,
intent(in) :: id_zi_native
541 integer :: id_xq, id_yq, id_zl, id_zi, id_xh, id_yh
542 integer :: i, j, k, nz, dl
543 real,
dimension(:),
pointer :: gridLonT_dsamp =>null()
544 real,
dimension(:),
pointer :: gridLatT_dsamp =>null()
545 real,
dimension(:),
pointer :: gridLonB_dsamp =>null()
546 real,
dimension(:),
pointer :: gridLatB_dsamp =>null()
548 id_zl = id_zl_native ; id_zi = id_zi_native
550 do dl=2,max_dsamp_lev
551 if(dl .ne. 2)
call mom_error(fatal,
"set_axes_info_dsamp: Downsample level other than 2 is not supported yet!")
552 if (g%symmetric)
then
553 allocate(gridlonb_dsamp(diag_cs%dsamp(dl)%isgB:diag_cs%dsamp(dl)%iegB))
554 allocate(gridlatb_dsamp(diag_cs%dsamp(dl)%jsgB:diag_cs%dsamp(dl)%jegB))
555 do i=diag_cs%dsamp(dl)%isgB,diag_cs%dsamp(dl)%iegB; gridlonb_dsamp(i) = g%gridLonB(g%isgB+dl*i);
enddo
556 do j=diag_cs%dsamp(dl)%jsgB,diag_cs%dsamp(dl)%jegB; gridlatb_dsamp(j) = g%gridLatB(g%jsgB+dl*j);
enddo
557 id_xq = diag_axis_init(
'xq', gridlonb_dsamp, g%x_axis_units,
'x', &
558 'q point nominal longitude', domain2=g%Domain%mpp_domain_d2)
559 id_yq = diag_axis_init(
'yq', gridlatb_dsamp, g%y_axis_units,
'y', &
560 'q point nominal latitude', domain2=g%Domain%mpp_domain_d2)
561 deallocate(gridlonb_dsamp,gridlatb_dsamp)
563 allocate(gridlonb_dsamp(diag_cs%dsamp(dl)%isg:diag_cs%dsamp(dl)%ieg))
564 allocate(gridlatb_dsamp(diag_cs%dsamp(dl)%jsg:diag_cs%dsamp(dl)%jeg))
565 do i=diag_cs%dsamp(dl)%isg,diag_cs%dsamp(dl)%ieg; gridlonb_dsamp(i) = g%gridLonB(g%isg+dl*i-2);
enddo
566 do j=diag_cs%dsamp(dl)%jsg,diag_cs%dsamp(dl)%jeg; gridlatb_dsamp(j) = g%gridLatB(g%jsg+dl*j-2);
enddo
567 id_xq = diag_axis_init(
'xq', gridlonb_dsamp, g%x_axis_units,
'x', &
568 'q point nominal longitude', domain2=g%Domain%mpp_domain_d2)
569 id_yq = diag_axis_init(
'yq', gridlatb_dsamp, g%y_axis_units,
'y', &
570 'q point nominal latitude', domain2=g%Domain%mpp_domain_d2)
571 deallocate(gridlonb_dsamp,gridlatb_dsamp)
574 allocate(gridlont_dsamp(diag_cs%dsamp(dl)%isg:diag_cs%dsamp(dl)%ieg))
575 allocate(gridlatt_dsamp(diag_cs%dsamp(dl)%jsg:diag_cs%dsamp(dl)%jeg))
576 do i=diag_cs%dsamp(dl)%isg,diag_cs%dsamp(dl)%ieg; gridlont_dsamp(i) = g%gridLonT(g%isg+dl*i-2);
enddo
577 do j=diag_cs%dsamp(dl)%jsg,diag_cs%dsamp(dl)%jeg; gridlatt_dsamp(j) = g%gridLatT(g%jsg+dl*j-2);
enddo
578 id_xh = diag_axis_init(
'xh', gridlont_dsamp, g%x_axis_units,
'x', &
579 'h point nominal longitude', domain2=g%Domain%mpp_domain_d2)
580 id_yh = diag_axis_init(
'yh', gridlatt_dsamp, g%y_axis_units,
'y', &
581 'h point nominal latitude', domain2=g%Domain%mpp_domain_d2)
583 deallocate(gridlont_dsamp,gridlatt_dsamp)
587 x_cell_method=
'mean', y_cell_method=
'mean', v_cell_method=
'mean', &
588 is_h_point=.true., is_layer=.true., xyave_axes=diag_cs%axesZL)
590 x_cell_method=
'point', y_cell_method=
'point', v_cell_method=
'mean', &
591 is_q_point=.true., is_layer=.true.)
593 x_cell_method=
'point', y_cell_method=
'mean', v_cell_method=
'mean', &
594 is_u_point=.true., is_layer=.true., xyave_axes=diag_cs%axesZL)
596 x_cell_method=
'mean', y_cell_method=
'point', v_cell_method=
'mean', &
597 is_v_point=.true., is_layer=.true., xyave_axes=diag_cs%axesZL)
601 x_cell_method=
'mean', y_cell_method=
'mean', v_cell_method=
'point', &
602 is_h_point=.true., is_interface=.true., xyave_axes=diag_cs%axesZi)
604 x_cell_method=
'point', y_cell_method=
'point', v_cell_method=
'point', &
605 is_q_point=.true., is_interface=.true.)
607 x_cell_method=
'point', y_cell_method=
'mean', v_cell_method=
'point', &
608 is_u_point=.true., is_interface=.true., xyave_axes=diag_cs%axesZi)
610 x_cell_method=
'mean', y_cell_method=
'point', v_cell_method=
'point', &
611 is_v_point=.true., is_interface=.true., xyave_axes=diag_cs%axesZi)
615 x_cell_method=
'mean', y_cell_method=
'mean', is_h_point=.true.)
617 x_cell_method=
'point', y_cell_method=
'point', is_q_point=.true.)
619 x_cell_method=
'point', y_cell_method=
'mean', is_u_point=.true.)
621 x_cell_method=
'mean', y_cell_method=
'point', is_v_point=.true.)
624 if (diag_cs%num_diag_coords>0)
then
625 allocate(diag_cs%dsamp(dl)%remap_axesTL(diag_cs%num_diag_coords))
626 allocate(diag_cs%dsamp(dl)%remap_axesBL(diag_cs%num_diag_coords))
627 allocate(diag_cs%dsamp(dl)%remap_axesCuL(diag_cs%num_diag_coords))
628 allocate(diag_cs%dsamp(dl)%remap_axesCvL(diag_cs%num_diag_coords))
629 allocate(diag_cs%dsamp(dl)%remap_axesTi(diag_cs%num_diag_coords))
630 allocate(diag_cs%dsamp(dl)%remap_axesBi(diag_cs%num_diag_coords))
631 allocate(diag_cs%dsamp(dl)%remap_axesCui(diag_cs%num_diag_coords))
632 allocate(diag_cs%dsamp(dl)%remap_axesCvi(diag_cs%num_diag_coords))
635 do i=1, diag_cs%num_diag_coords
640 if (diag_remap_axes_configured(diag_cs%diag_remap_cs(i)))
then
644 call diag_remap_get_axes_info(diag_cs%diag_remap_cs(i), nz, id_zl, id_zi)
648 nz=nz, vertical_coordinate_number=i, &
649 x_cell_method=
'mean', y_cell_method=
'mean', v_cell_method=
'mean', &
650 is_h_point=.true., is_layer=.true., is_native=.false., needs_remapping=.true., &
651 xyave_axes=diag_cs%remap_axesZL(i))
656 nz=nz, vertical_coordinate_number=i, &
657 x_cell_method=
'point', y_cell_method=
'point', v_cell_method=
'mean', &
658 is_q_point=.true., is_layer=.true., is_native=.false.)
661 nz=nz, vertical_coordinate_number=i, &
662 x_cell_method=
'point', y_cell_method=
'mean', v_cell_method=
'mean', &
663 is_u_point=.true., is_layer=.true., is_native=.false., needs_remapping=.true., &
664 xyave_axes=diag_cs%remap_axesZL(i))
667 nz=nz, vertical_coordinate_number=i, &
668 x_cell_method=
'mean', y_cell_method=
'point', v_cell_method=
'mean', &
669 is_v_point=.true., is_layer=.true., is_native=.false., needs_remapping=.true., &
670 xyave_axes=diag_cs%remap_axesZL(i))
674 nz=nz, vertical_coordinate_number=i, &
675 x_cell_method=
'mean', y_cell_method=
'mean', v_cell_method=
'point', &
676 is_h_point=.true., is_interface=.true., is_native=.false., needs_interpolating=.true., &
677 xyave_axes=diag_cs%remap_axesZi(i))
681 nz=nz, vertical_coordinate_number=i, &
682 x_cell_method=
'point', y_cell_method=
'point', v_cell_method=
'point', &
683 is_q_point=.true., is_interface=.true., is_native=.false.)
686 nz=nz, vertical_coordinate_number=i, &
687 x_cell_method=
'point', y_cell_method=
'mean', v_cell_method=
'point', &
688 is_u_point=.true., is_interface=.true., is_native=.false., &
689 needs_interpolating=.true., xyave_axes=diag_cs%remap_axesZi(i))
692 nz=nz, vertical_coordinate_number=i, &
693 x_cell_method=
'mean', y_cell_method=
'point', v_cell_method=
'point', &
694 is_v_point=.true., is_interface=.true., is_native=.false., &
695 needs_interpolating=.true., xyave_axes=diag_cs%remap_axesZi(i))
710 integer :: c, nk, i, j, k, ii, jj
711 type(
axes_grp),
pointer :: axes => null(), h_axes => null()
713 do c=1, diag_cs%num_diag_coords
715 if (diag_remap_axes_configured(diag_cs%diag_remap_cs(c)))
then
718 axes => diag_cs%remap_axesTL(c)
720 allocate( axes%mask3d(g%isd:g%ied,g%jsd:g%jed,nk) ) ; axes%mask3d(:,:,:) = 0.
721 call diag_remap_calc_hmask(diag_cs%diag_remap_cs(c), g, axes%mask3d)
723 h_axes => diag_cs%remap_axesTL(c)
726 axes => diag_cs%remap_axesCuL(c)
727 call assert(axes%nz == nk,
'set_masks_for_axes: vertical size mismatch at u-layers')
728 call assert(.not.
associated(axes%mask3d),
'set_masks_for_axes: already associated')
729 allocate( axes%mask3d(g%IsdB:g%IedB,g%jsd:g%jed,nk) ) ; axes%mask3d(:,:,:) = 0.
730 do k = 1, nk ;
do j=g%jsc,g%jec ;
do i=g%isc-1,g%iec
731 if (h_axes%mask3d(i,j,k) + h_axes%mask3d(i+1,j,k) > 0.) axes%mask3d(i,j,k) = 1.
732 enddo ;
enddo ;
enddo
735 axes => diag_cs%remap_axesCvL(c)
736 call assert(axes%nz == nk,
'set_masks_for_axes: vertical size mismatch at v-layers')
737 call assert(.not.
associated(axes%mask3d),
'set_masks_for_axes: already associated')
738 allocate( axes%mask3d(g%isd:g%ied,g%JsdB:g%JedB,nk) ) ; axes%mask3d(:,:,:) = 0.
739 do k = 1, nk ;
do j=g%jsc-1,g%jec ;
do i=g%isc,g%iec
740 if (h_axes%mask3d(i,j,k) + h_axes%mask3d(i,j+1,k) > 0.) axes%mask3d(i,j,k) = 1.
741 enddo ;
enddo ;
enddo
744 axes => diag_cs%remap_axesBL(c)
745 call assert(axes%nz == nk,
'set_masks_for_axes: vertical size mismatch at q-layers')
746 call assert(.not.
associated(axes%mask3d),
'set_masks_for_axes: already associated')
747 allocate( axes%mask3d(g%IsdB:g%IedB,g%JsdB:g%JedB,nk) ) ; axes%mask3d(:,:,:) = 0.
748 do k = 1, nk ;
do j=g%jsc-1,g%jec ;
do i=g%isc-1,g%iec
749 if (h_axes%mask3d(i,j,k) + h_axes%mask3d(i+1,j+1,k) + &
750 h_axes%mask3d(i+1,j,k) + h_axes%mask3d(i,j+1,k) > 0.) axes%mask3d(i,j,k) = 1.
751 enddo ;
enddo ;
enddo
754 axes => diag_cs%remap_axesTi(c)
755 call assert(axes%nz == nk,
'set_masks_for_axes: vertical size mismatch at h-interfaces')
756 call assert(.not.
associated(axes%mask3d),
'set_masks_for_axes: already associated')
757 allocate( axes%mask3d(g%isd:g%ied,g%jsd:g%jed,nk+1) ) ; axes%mask3d(:,:,:) = 0.
758 do j=g%jsc-1,g%jec+1 ;
do i=g%isc-1,g%iec+1
759 if (h_axes%mask3d(i,j,1) > 0.) axes%mask3d(i,j,1) = 1.
761 if (h_axes%mask3d(i,j,k-1) + h_axes%mask3d(i,j,k) > 0.) axes%mask3d(i,j,k) = 1.
763 if (h_axes%mask3d(i,j,nk) > 0.) axes%mask3d(i,j,nk+1) = 1.
766 h_axes => diag_cs%remap_axesTi(c)
769 axes => diag_cs%remap_axesCui(c)
770 call assert(axes%nz == nk,
'set_masks_for_axes: vertical size mismatch at u-interfaces')
771 call assert(.not.
associated(axes%mask3d),
'set_masks_for_axes: already associated')
772 allocate( axes%mask3d(g%IsdB:g%IedB,g%jsd:g%jed,nk+1) ) ; axes%mask3d(:,:,:) = 0.
773 do k = 1, nk+1 ;
do j=g%jsc,g%jec ;
do i=g%isc-1,g%iec
774 if (h_axes%mask3d(i,j,k) + h_axes%mask3d(i+1,j,k) > 0.) axes%mask3d(i,j,k) = 1.
775 enddo ;
enddo ;
enddo
778 axes => diag_cs%remap_axesCvi(c)
779 call assert(axes%nz == nk,
'set_masks_for_axes: vertical size mismatch at v-interfaces')
780 call assert(.not.
associated(axes%mask3d),
'set_masks_for_axes: already associated')
781 allocate( axes%mask3d(g%isd:g%ied,g%JsdB:g%JedB,nk+1) ) ; axes%mask3d(:,:,:) = 0.
782 do k = 1, nk+1 ;
do j=g%jsc-1,g%jec ;
do i=g%isc,g%iec
783 if (h_axes%mask3d(i,j,k) + h_axes%mask3d(i,j+1,k) > 0.) axes%mask3d(i,j,k) = 1.
784 enddo ;
enddo ;
enddo
787 axes => diag_cs%remap_axesBi(c)
788 call assert(axes%nz == nk,
'set_masks_for_axes: vertical size mismatch at q-interfaces')
789 call assert(.not.
associated(axes%mask3d),
'set_masks_for_axes: already associated')
790 allocate( axes%mask3d(g%IsdB:g%IedB,g%JsdB:g%JedB,nk+1) ) ; axes%mask3d(:,:,:) = 0.
791 do k = 1, nk ;
do j=g%jsc-1,g%jec ;
do i=g%isc-1,g%iec
792 if (h_axes%mask3d(i,j,k) + h_axes%mask3d(i+1,j+1,k) + &
793 h_axes%mask3d(i+1,j,k) + h_axes%mask3d(i,j+1,k) > 0.) axes%mask3d(i,j,k) = 1.
794 enddo ;
enddo ;
enddo
808 integer :: c, nk, i, j, k, ii, jj
810 type(
axes_grp),
pointer :: axes => null(), h_axes => null()
815 do dl=2,max_dsamp_lev
816 if(dl .ne. 2)
call mom_error(fatal,
"set_masks_for_axes_dsamp: Downsample level other than 2 is not supported!")
817 do c=1, diag_cs%num_diag_coords
819 axes => diag_cs%remap_axesTL(c)
820 call downsample_mask(axes%mask3d, diag_cs%dsamp(dl)%remap_axesTL(c)%dsamp(dl)%mask3d, dl,g%isc, g%jsc, &
821 g%HId2%isc, g%HId2%iec, g%HId2%jsc, g%HId2%jec, g%HId2%isd, g%HId2%ied, g%HId2%jsd, g%HId2%jed)
822 diag_cs%dsamp(dl)%remap_axesTL(c)%mask3d => axes%mask3d
824 axes => diag_cs%remap_axesCuL(c)
825 call downsample_mask(axes%mask3d, diag_cs%dsamp(dl)%remap_axesCuL(c)%dsamp(dl)%mask3d, dl,g%IscB,g%JscB, &
826 g%HId2%IscB,g%HId2%IecB,g%HId2%jsc, g%HId2%jec,g%HId2%IsdB,g%HId2%IedB,g%HId2%jsd, g%HId2%jed)
827 diag_cs%dsamp(dl)%remap_axesCul(c)%mask3d => axes%mask3d
829 axes => diag_cs%remap_axesCvL(c)
830 call downsample_mask(axes%mask3d, diag_cs%dsamp(dl)%remap_axesCvL(c)%dsamp(dl)%mask3d, dl,g%isc ,g%JscB, &
831 g%HId2%isc ,g%HId2%iec, g%HId2%JscB,g%HId2%JecB,g%HId2%isd ,g%HId2%ied, g%HId2%JsdB,g%HId2%JedB)
832 diag_cs%dsamp(dl)%remap_axesCvL(c)%mask3d => axes%mask3d
834 axes => diag_cs%remap_axesBL(c)
835 call downsample_mask(axes%mask3d, diag_cs%dsamp(dl)%remap_axesBL(c)%dsamp(dl)%mask3d, dl,g%IscB,g%JscB, &
836 g%HId2%IscB,g%HId2%IecB,g%HId2%JscB,g%HId2%JecB,g%HId2%IsdB,g%HId2%IedB,g%HId2%JsdB,g%HId2%JedB)
837 diag_cs%dsamp(dl)%remap_axesBL(c)%mask3d => axes%mask3d
839 axes => diag_cs%remap_axesTi(c)
840 call downsample_mask(axes%mask3d, diag_cs%dsamp(dl)%remap_axesTi(c)%dsamp(dl)%mask3d, dl,g%isc, g%jsc, &
841 g%HId2%isc, g%HId2%iec, g%HId2%jsc, g%HId2%jec, g%HId2%isd, g%HId2%ied, g%HId2%jsd, g%HId2%jed)
842 diag_cs%dsamp(dl)%remap_axesTi(c)%mask3d => axes%mask3d
844 axes => diag_cs%remap_axesCui(c)
845 call downsample_mask(axes%mask3d, diag_cs%dsamp(dl)%remap_axesCui(c)%dsamp(dl)%mask3d, dl,g%IscB,g%JscB, &
846 g%HId2%IscB,g%HId2%IecB,g%HId2%jsc, g%HId2%jec,g%HId2%IsdB,g%HId2%IedB,g%HId2%jsd, g%HId2%jed)
847 diag_cs%dsamp(dl)%remap_axesCui(c)%mask3d => axes%mask3d
849 axes => diag_cs%remap_axesCvi(c)
850 call downsample_mask(axes%mask3d, diag_cs%dsamp(dl)%remap_axesCvi(c)%dsamp(dl)%mask3d, dl,g%isc ,g%JscB, &
851 g%HId2%isc ,g%HId2%iec, g%HId2%JscB,g%HId2%JecB,g%HId2%isd ,g%HId2%ied, g%HId2%JsdB,g%HId2%JedB)
852 diag_cs%dsamp(dl)%remap_axesCvi(c)%mask3d => axes%mask3d
854 axes => diag_cs%remap_axesBi(c)
855 call downsample_mask(axes%mask3d, diag_cs%dsamp(dl)%remap_axesBi(c)%dsamp(dl)%mask3d, dl,g%IscB,g%JscB, &
856 g%HId2%IscB,g%HId2%IecB,g%HId2%JscB,g%HId2%JecB,g%HId2%IsdB,g%HId2%IedB,g%HId2%JsdB,g%HId2%JedB)
857 diag_cs%dsamp(dl)%remap_axesBi(c)%mask3d => axes%mask3d
865 integer,
optional,
intent(in) :: id_area_t
866 integer,
optional,
intent(in) :: id_area_q
869 if (
present(id_area_t))
then
870 fms_id = diag_cs%diags(id_area_t)%fms_diag_id
871 diag_cs%axesT1%id_area = fms_id
872 diag_cs%axesTi%id_area = fms_id
873 diag_cs%axesTL%id_area = fms_id
874 do i=1, diag_cs%num_diag_coords
875 diag_cs%remap_axesTL(i)%id_area = fms_id
876 diag_cs%remap_axesTi(i)%id_area = fms_id
879 if (
present(id_area_q))
then
880 fms_id = diag_cs%diags(id_area_q)%fms_diag_id
881 diag_cs%axesB1%id_area = fms_id
882 diag_cs%axesBi%id_area = fms_id
883 diag_cs%axesBL%id_area = fms_id
884 do i=1, diag_cs%num_diag_coords
885 diag_cs%remap_axesBL(i)%id_area = fms_id
886 diag_cs%remap_axesBi(i)%id_area = fms_id
894 type(
diag_ctrl),
target,
intent(inout) :: diag
895 type(time_type),
intent(in) :: time
899 time,
'Ocean grid-cell volume',
'm3', &
900 standard_name=
'ocean_volume', v_extensive=.true., &
901 x_cell_method=
'sum', y_cell_method=
'sum')
909 integer,
intent(in) :: id_h_volume
911 type(
diag_type),
pointer :: tmp => null()
913 if (id_h_volume<=0)
return
914 diag_cs%volume_cell_measure_dm_id = id_h_volume
917 diag_cs%diags(id_h_volume)%axes%id_volume = diag_cs%diags(id_h_volume)%fms_diag_id
919 tmp => diag_cs%diags(id_h_volume)%next
920 do while (
associated(tmp))
922 tmp%axes%id_volume = tmp%fms_diag_id
937 subroutine define_axes_group(diag_cs, handles, axes, nz, vertical_coordinate_number, &
938 x_cell_method, y_cell_method, v_cell_method, &
939 is_h_point, is_q_point, is_u_point, is_v_point, &
940 is_layer, is_interface, &
941 is_native, needs_remapping, needs_interpolating, &
944 integer,
dimension(:),
intent(in) :: handles
946 integer,
optional,
intent(in) :: nz
947 integer,
optional,
intent(in) :: vertical_coordinate_number
948 character(len=*),
optional,
intent(in) :: x_cell_method
950 character(len=*),
optional,
intent(in) :: y_cell_method
952 character(len=*),
optional,
intent(in) :: v_cell_method
954 logical,
optional,
intent(in) :: is_h_point
956 logical,
optional,
intent(in) :: is_q_point
958 logical,
optional,
intent(in) :: is_u_point
960 logical,
optional,
intent(in) :: is_v_point
962 logical,
optional,
intent(in) :: is_layer
964 logical,
optional,
intent(in) :: is_interface
966 logical,
optional,
intent(in) :: is_native
968 logical,
optional,
intent(in) :: needs_remapping
971 logical,
optional,
intent(in) :: needs_interpolating
974 type(
axes_grp),
optional,
target :: xyave_axes
980 if (n<1 .or. n>3)
call mom_error(fatal,
"define_axes_group: wrong size for list of handles!")
981 allocate( axes%handles(n) )
982 axes%id =
i2s(handles, n)
984 axes%handles(:) = handles(:)
985 axes%diag_cs => diag_cs
986 if (
present(x_cell_method))
then
987 if (axes%rank<2)
call mom_error(fatal,
'define_axes_group: ' // &
988 'Can not set x_cell_method for rank<2.')
989 axes%x_cell_method = trim(x_cell_method)
991 axes%x_cell_method =
''
993 if (
present(y_cell_method))
then
994 if (axes%rank<2)
call mom_error(fatal,
'define_axes_group: ' // &
995 'Can not set y_cell_method for rank<2.')
996 axes%y_cell_method = trim(y_cell_method)
998 axes%y_cell_method =
''
1000 if (
present(v_cell_method))
then
1001 if (axes%rank/=1 .and. axes%rank/=3)
call mom_error(fatal,
'define_axes_group: ' // &
1002 'Can not set v_cell_method for rank<>1 or 3.')
1003 axes%v_cell_method = trim(v_cell_method)
1005 axes%v_cell_method =
''
1007 if (
present(nz)) axes%nz = nz
1008 if (
present(vertical_coordinate_number)) axes%vertical_coordinate_number = vertical_coordinate_number
1009 if (
present(is_h_point)) axes%is_h_point = is_h_point
1010 if (
present(is_q_point)) axes%is_q_point = is_q_point
1011 if (
present(is_u_point)) axes%is_u_point = is_u_point
1012 if (
present(is_v_point)) axes%is_v_point = is_v_point
1013 if (
present(is_layer)) axes%is_layer = is_layer
1014 if (
present(is_interface)) axes%is_interface = is_interface
1015 if (
present(is_native)) axes%is_native = is_native
1016 if (
present(needs_remapping)) axes%needs_remapping = needs_remapping
1017 if (
present(needs_interpolating)) axes%needs_interpolating = needs_interpolating
1018 if (
present(xyave_axes)) axes%xyave_axes => xyave_axes
1021 axes%mask2d => null()
1022 if (axes%rank==2)
then
1023 if (axes%is_h_point) axes%mask2d => diag_cs%mask2dT
1024 if (axes%is_u_point) axes%mask2d => diag_cs%mask2dCu
1025 if (axes%is_v_point) axes%mask2d => diag_cs%mask2dCv
1026 if (axes%is_q_point) axes%mask2d => diag_cs%mask2dBu
1029 axes%mask3d => null()
1030 if (axes%rank==3 .and. axes%is_native)
then
1032 if (axes%is_layer)
then
1033 if (axes%is_h_point) axes%mask3d => diag_cs%mask3dTL
1034 if (axes%is_u_point) axes%mask3d => diag_cs%mask3dCuL
1035 if (axes%is_v_point) axes%mask3d => diag_cs%mask3dCvL
1036 if (axes%is_q_point) axes%mask3d => diag_cs%mask3dBL
1037 elseif (axes%is_interface)
then
1038 if (axes%is_h_point) axes%mask3d => diag_cs%mask3dTi
1039 if (axes%is_u_point) axes%mask3d => diag_cs%mask3dCui
1040 if (axes%is_v_point) axes%mask3d => diag_cs%mask3dCvi
1041 if (axes%is_q_point) axes%mask3d => diag_cs%mask3dBi
1049 x_cell_method, y_cell_method, v_cell_method, &
1050 is_h_point, is_q_point, is_u_point, is_v_point, &
1051 is_layer, is_interface, &
1052 is_native, needs_remapping, needs_interpolating, &
1055 integer,
dimension(:),
intent(in) :: handles
1056 type(
axes_grp),
intent(out) :: axes
1057 integer,
intent(in) :: dl
1058 integer,
optional,
intent(in) :: nz
1059 integer,
optional,
intent(in) :: vertical_coordinate_number
1060 character(len=*),
optional,
intent(in) :: x_cell_method
1062 character(len=*),
optional,
intent(in) :: y_cell_method
1064 character(len=*),
optional,
intent(in) :: v_cell_method
1066 logical,
optional,
intent(in) :: is_h_point
1068 logical,
optional,
intent(in) :: is_q_point
1070 logical,
optional,
intent(in) :: is_u_point
1072 logical,
optional,
intent(in) :: is_v_point
1074 logical,
optional,
intent(in) :: is_layer
1076 logical,
optional,
intent(in) :: is_interface
1078 logical,
optional,
intent(in) :: is_native
1080 logical,
optional,
intent(in) :: needs_remapping
1083 logical,
optional,
intent(in) :: needs_interpolating
1086 type(
axes_grp),
optional,
target :: xyave_axes
1092 if (n<1 .or. n>3)
call mom_error(fatal,
"define_axes_group: wrong size for list of handles!")
1093 allocate( axes%handles(n) )
1094 axes%id =
i2s(handles, n)
1096 axes%handles(:) = handles(:)
1097 axes%diag_cs => diag_cs
1098 if (
present(x_cell_method))
then
1099 if (axes%rank<2)
call mom_error(fatal,
'define_axes_group: ' // &
1100 'Can not set x_cell_method for rank<2.')
1101 axes%x_cell_method = trim(x_cell_method)
1103 axes%x_cell_method =
''
1105 if (
present(y_cell_method))
then
1106 if (axes%rank<2)
call mom_error(fatal,
'define_axes_group: ' // &
1107 'Can not set y_cell_method for rank<2.')
1108 axes%y_cell_method = trim(y_cell_method)
1110 axes%y_cell_method =
''
1112 if (
present(v_cell_method))
then
1113 if (axes%rank/=1 .and. axes%rank/=3)
call mom_error(fatal,
'define_axes_group: ' // &
1114 'Can not set v_cell_method for rank<>1 or 3.')
1115 axes%v_cell_method = trim(v_cell_method)
1117 axes%v_cell_method =
''
1119 axes%downsample_level = dl
1120 if (
present(nz)) axes%nz = nz
1121 if (
present(vertical_coordinate_number)) axes%vertical_coordinate_number = vertical_coordinate_number
1122 if (
present(is_h_point)) axes%is_h_point = is_h_point
1123 if (
present(is_q_point)) axes%is_q_point = is_q_point
1124 if (
present(is_u_point)) axes%is_u_point = is_u_point
1125 if (
present(is_v_point)) axes%is_v_point = is_v_point
1126 if (
present(is_layer)) axes%is_layer = is_layer
1127 if (
present(is_interface)) axes%is_interface = is_interface
1128 if (
present(is_native)) axes%is_native = is_native
1129 if (
present(needs_remapping)) axes%needs_remapping = needs_remapping
1130 if (
present(needs_interpolating)) axes%needs_interpolating = needs_interpolating
1131 if (
present(xyave_axes)) axes%xyave_axes => xyave_axes
1135 axes%mask2d => null()
1136 if (axes%rank==2)
then
1137 if (axes%is_h_point) axes%mask2d => diag_cs%mask2dT
1138 if (axes%is_u_point) axes%mask2d => diag_cs%mask2dCu
1139 if (axes%is_v_point) axes%mask2d => diag_cs%mask2dCv
1140 if (axes%is_q_point) axes%mask2d => diag_cs%mask2dBu
1143 axes%mask3d => null()
1144 if (axes%rank==3 .and. axes%is_native)
then
1146 if (axes%is_layer)
then
1147 if (axes%is_h_point) axes%mask3d => diag_cs%mask3dTL
1148 if (axes%is_u_point) axes%mask3d => diag_cs%mask3dCuL
1149 if (axes%is_v_point) axes%mask3d => diag_cs%mask3dCvL
1150 if (axes%is_q_point) axes%mask3d => diag_cs%mask3dBL
1151 elseif (axes%is_interface)
then
1152 if (axes%is_h_point) axes%mask3d => diag_cs%mask3dTi
1153 if (axes%is_u_point) axes%mask3d => diag_cs%mask3dCui
1154 if (axes%is_v_point) axes%mask3d => diag_cs%mask3dCvi
1155 if (axes%is_q_point) axes%mask3d => diag_cs%mask3dBi
1159 axes%dsamp(dl)%mask2d => null()
1160 if (axes%rank==2)
then
1161 if (axes%is_h_point) axes%dsamp(dl)%mask2d => diag_cs%dsamp(dl)%mask2dT
1162 if (axes%is_u_point) axes%dsamp(dl)%mask2d => diag_cs%dsamp(dl)%mask2dCu
1163 if (axes%is_v_point) axes%dsamp(dl)%mask2d => diag_cs%dsamp(dl)%mask2dCv
1164 if (axes%is_q_point) axes%dsamp(dl)%mask2d => diag_cs%dsamp(dl)%mask2dBu
1167 axes%dsamp(dl)%mask3d => null()
1168 if (axes%rank==3 .and. axes%is_native)
then
1170 if (axes%is_layer)
then
1171 if (axes%is_h_point) axes%dsamp(dl)%mask3d => diag_cs%dsamp(dl)%mask3dTL
1172 if (axes%is_u_point) axes%dsamp(dl)%mask3d => diag_cs%dsamp(dl)%mask3dCuL
1173 if (axes%is_v_point) axes%dsamp(dl)%mask3d => diag_cs%dsamp(dl)%mask3dCvL
1174 if (axes%is_q_point) axes%dsamp(dl)%mask3d => diag_cs%dsamp(dl)%mask3dBL
1175 elseif (axes%is_interface)
then
1176 if (axes%is_h_point) axes%dsamp(dl)%mask3d => diag_cs%dsamp(dl)%mask3dTi
1177 if (axes%is_u_point) axes%dsamp(dl)%mask3d => diag_cs%dsamp(dl)%mask3dCui
1178 if (axes%is_v_point) axes%dsamp(dl)%mask3d => diag_cs%dsamp(dl)%mask3dCvi
1179 if (axes%is_q_point) axes%dsamp(dl)%mask3d => diag_cs%dsamp(dl)%mask3dBi
1188 type(
diag_ctrl),
intent(inout) :: diag_cs
1190 diag_cs%is = g%isc - (g%isd-1) ; diag_cs%ie = g%iec - (g%isd-1)
1191 diag_cs%js = g%jsc - (g%jsd-1) ; diag_cs%je = g%jec - (g%jsd-1)
1192 diag_cs%isd = g%isd ; diag_cs%ied = g%ied
1193 diag_cs%jsd = g%jsd ; diag_cs%jed = g%jed
1198 subroutine post_data_0d(diag_field_id, field, diag_cs, is_static)
1199 integer,
intent(in) :: diag_field_id
1201 real,
intent(in) :: field
1202 type(
diag_ctrl),
target,
intent(in) :: diag_CS
1203 logical,
optional,
intent(in) :: is_static
1206 logical :: used, is_stat
1207 type(
diag_type),
pointer :: diag => null()
1210 is_stat = .false. ;
if (
present(is_static)) is_stat = is_static
1214 call assert(diag_field_id < diag_cs%next_free_diag_id, &
1215 'post_data_0d: Unregistered diagnostic id')
1216 diag => diag_cs%diags(diag_field_id)
1217 do while (
associated(diag))
1218 if (diag_cs%diag_as_chksum)
then
1219 call chksum0(field, diag%debug_str, logunit=diag_cs%chksum_iounit)
1220 else if (is_stat)
then
1221 used = send_data(diag%fms_diag_id, field)
1222 elseif (diag_cs%ave_enabled)
then
1223 used = send_data(diag%fms_diag_id, field, diag_cs%time_end)
1232 subroutine post_data_1d_k(diag_field_id, field, diag_cs, is_static)
1233 integer,
intent(in) :: diag_field_id
1235 real,
target,
intent(in) :: field(:)
1236 type(
diag_ctrl),
target,
intent(in) :: diag_cs
1237 logical,
optional,
intent(in) :: is_static
1241 real,
dimension(:),
pointer :: locfield => null()
1243 integer :: k, ks, ke
1244 type(
diag_type),
pointer :: diag => null()
1247 is_stat = .false. ;
if (
present(is_static)) is_stat = is_static
1250 call assert(diag_field_id < diag_cs%next_free_diag_id, &
1251 'post_data_1d_k: Unregistered diagnostic id')
1252 diag => diag_cs%diags(diag_field_id)
1253 do while (
associated(diag))
1255 if ((diag%conversion_factor /= 0.) .and. (diag%conversion_factor /= 1.))
then
1256 ks = lbound(field,1) ; ke = ubound(field,1)
1257 allocate( locfield( ks:ke ) )
1260 if (field(k) == diag_cs%missing_value)
then
1261 locfield(k) = diag_cs%missing_value
1263 locfield(k) = field(k) * diag%conversion_factor
1270 if (diag_cs%diag_as_chksum)
then
1271 call zchksum(locfield, diag%debug_str, logunit=diag_cs%chksum_iounit)
1272 else if (is_stat)
then
1273 used = send_data(diag%fms_diag_id, locfield)
1274 elseif (diag_cs%ave_enabled)
then
1275 used = send_data(diag%fms_diag_id, locfield, diag_cs%time_end, weight=diag_cs%time_int)
1277 if ((diag%conversion_factor /= 0.) .and. (diag%conversion_factor /= 1.))
deallocate( locfield )
1286 subroutine post_data_2d(diag_field_id, field, diag_cs, is_static, mask)
1287 integer,
intent(in) :: diag_field_id
1289 real,
intent(in) :: field(:,:)
1290 type(
diag_ctrl),
target,
intent(in) :: diag_CS
1291 logical,
optional,
intent(in) :: is_static
1292 real,
optional,
intent(in) :: mask(:,:)
1295 type(
diag_type),
pointer :: diag => null()
1300 call assert(diag_field_id < diag_cs%next_free_diag_id, &
1301 'post_data_2d: Unregistered diagnostic id')
1302 diag => diag_cs%diags(diag_field_id)
1303 do while (
associated(diag))
1315 real,
target,
intent(in) :: field(:,:)
1317 logical,
optional,
intent(in) :: is_static
1318 real,
optional,
target,
intent(in) :: mask(:,:)
1321 real,
dimension(:,:),
pointer :: locfield
1322 real,
dimension(:,:),
pointer :: locmask
1323 character(len=300) :: mesg
1324 logical :: used, is_stat
1325 integer :: cszi, cszj, dszi, dszj
1326 integer :: isv, iev, jsv, jev, i, j, chksum, isv_o,jsv_o
1327 real,
dimension(:,:),
allocatable,
target :: locfield_dsamp
1328 real,
dimension(:,:),
allocatable,
target :: locmask_dsamp
1333 is_stat = .false. ;
if (
present(is_static)) is_stat = is_static
1340 isv = diag_cs%is ; iev = diag_cs%ie ; jsv = diag_cs%js ; jev = diag_cs%je
1342 cszi = diag_cs%ie-diag_cs%is +1 ; dszi = diag_cs%ied-diag_cs%isd +1
1343 cszj = diag_cs%je-diag_cs%js +1 ; dszj = diag_cs%jed-diag_cs%jsd +1
1344 if (
size(field,1) == dszi )
then
1345 isv = diag_cs%is ; iev = diag_cs%ie
1346 elseif (
size(field,1) == dszi + 1 )
then
1347 isv = diag_cs%is ; iev = diag_cs%ie+1
1348 elseif (
size(field,1) == cszi)
then
1349 isv = 1 ; iev = cszi
1350 elseif (
size(field,1) == cszi + 1 )
then
1351 isv = 1 ; iev = cszi+1
1353 write (mesg,*)
" peculiar size ",
size(field,1),
" in i-direction\n"//&
1354 "does not match one of ", cszi, cszi+1, dszi, dszi+1
1355 call mom_error(fatal,
"post_data_2d_low: "//trim(diag%debug_str)//trim(mesg))
1358 if (
size(field,2) == dszj )
then
1359 jsv = diag_cs%js ; jev = diag_cs%je
1360 elseif (
size(field,2) == dszj + 1 )
then
1361 jsv = diag_cs%js ; jev = diag_cs%je+1
1362 elseif (
size(field,2) == cszj )
then
1363 jsv = 1 ; jev = cszj
1364 elseif (
size(field,2) == cszj+1 )
then
1365 jsv = 1 ; jev = cszj+1
1367 write (mesg,*)
" peculiar size ",
size(field,2),
" in j-direction\n"//&
1368 "does not match one of ", cszj, cszj+1, dszj, dszj+1
1369 call mom_error(fatal,
"post_data_2d_low: "//trim(diag%debug_str)//trim(mesg))
1372 if ((diag%conversion_factor /= 0.) .and. (diag%conversion_factor /= 1.))
then
1373 allocate( locfield( lbound(field,1):ubound(field,1), lbound(field,2):ubound(field,2) ) )
1374 do j=jsv,jev ;
do i=isv,iev
1375 if (field(i,j) == diag_cs%missing_value)
then
1376 locfield(i,j) = diag_cs%missing_value
1378 locfield(i,j) = field(i,j) * diag%conversion_factor
1381 locfield(isv:iev,jsv:jev) = field(isv:iev,jsv:jev) * diag%conversion_factor
1386 if (
present(mask))
then
1388 elseif(.NOT. is_stat)
then
1389 if(
associated(diag%axes%mask2d)) locmask => diag%axes%mask2d
1393 if(.NOT. is_stat) dl = diag%axes%downsample_level
1396 isv_o=isv ; jsv_o=jsv
1398 if ((diag%conversion_factor /= 0.) .and. (diag%conversion_factor /= 1.))
deallocate( locfield )
1399 locfield => locfield_dsamp
1400 if (
present(mask))
then
1401 call downsample_field_2d(locmask, locmask_dsamp, dl,
msk, locmask, diag_cs,diag,isv_o,jsv_o,isv,iev,jsv,jev)
1402 locmask => locmask_dsamp
1403 elseif(
associated(diag%axes%dsamp(dl)%mask2d))
then
1404 locmask => diag%axes%dsamp(dl)%mask2d
1408 if (diag_cs%diag_as_chksum)
then
1409 if (diag%axes%is_h_point)
then
1410 call hchksum(locfield, diag%debug_str, diag_cs%G%HI, &
1411 logunit=diag_cs%chksum_iounit)
1412 else if (diag%axes%is_u_point)
then
1413 call uchksum(locfield, diag%debug_str, diag_cs%G%HI, &
1414 logunit=diag_cs%chksum_iounit)
1415 else if (diag%axes%is_v_point)
then
1416 call vchksum(locfield, diag%debug_str, diag_cs%G%HI, &
1417 logunit=diag_cs%chksum_iounit)
1418 else if (diag%axes%is_q_point)
then
1419 call bchksum(locfield, diag%debug_str, diag_cs%G%HI, &
1420 logunit=diag_cs%chksum_iounit)
1422 call mom_error(fatal,
"post_data_2d_low: unknown axis type.")
1426 if (
present(mask))
then
1427 call assert(
size(locfield) ==
size(locmask), &
1428 'post_data_2d_low is_stat: mask size mismatch: '//diag%debug_str)
1429 used = send_data(diag%fms_diag_id, locfield, &
1430 is_in=isv, js_in=jsv, ie_in=iev, je_in=jev, rmask=locmask)
1435 used = send_data(diag%fms_diag_id, locfield, &
1436 is_in=isv, js_in=jsv, ie_in=iev, je_in=jev)
1438 elseif (diag_cs%ave_enabled)
then
1439 if (
associated(locmask))
then
1440 call assert(
size(locfield) ==
size(locmask), &
1441 'post_data_2d_low: mask size mismatch: '//diag%debug_str)
1442 used = send_data(diag%fms_diag_id, locfield, diag_cs%time_end, &
1443 is_in=isv, js_in=jsv, ie_in=iev, je_in=jev, &
1444 weight=diag_cs%time_int, rmask=locmask)
1446 used = send_data(diag%fms_diag_id, locfield, diag_cs%time_end, &
1447 is_in=isv, js_in=jsv, ie_in=iev, je_in=jev, &
1448 weight=diag_cs%time_int)
1452 if ((diag%conversion_factor /= 0.) .and. (diag%conversion_factor /= 1.) .and. dl<2) &
1453 deallocate( locfield )
1457 subroutine post_data_3d(diag_field_id, field, diag_cs, is_static, mask, alt_h)
1459 integer,
intent(in) :: diag_field_id
1461 real,
intent(in) :: field(:,:,:)
1462 type(
diag_ctrl),
target,
intent(in) :: diag_CS
1463 logical,
optional,
intent(in) :: is_static
1464 real,
optional,
intent(in) :: mask(:,:,:)
1465 real,
dimension(:,:,:), &
1466 target,
optional,
intent(in) :: alt_h
1470 type(
diag_type),
pointer :: diag => null()
1471 integer :: nz, i, j, k
1472 real,
dimension(:,:,:),
allocatable :: remapped_field
1473 logical :: staggered_in_x, staggered_in_y
1474 real,
dimension(:,:,:),
pointer :: h_diag => null()
1476 if (
present(alt_h))
then
1486 call assert(diag_field_id < diag_cs%next_free_diag_id, &
1487 'post_data_3d: Unregistered diagnostic id')
1488 diag => diag_cs%diags(diag_field_id)
1489 do while (
associated(diag))
1490 call assert(
associated(diag%axes),
'post_data_3d: axes is not associated')
1492 staggered_in_x = diag%axes%is_u_point .or. diag%axes%is_q_point
1493 staggered_in_y = diag%axes%is_v_point .or. diag%axes%is_q_point
1495 if (diag%v_extensive .and. .not.diag%axes%is_native)
then
1497 if (
present(mask))
then
1498 call mom_error(fatal,
"post_data_3d: no mask for regridded field.")
1502 allocate(remapped_field(
size(field,1),
size(field,2), diag%axes%nz))
1503 call vertically_reintegrate_diag_field( &
1504 diag_cs%diag_remap_cs(diag%axes%vertical_coordinate_number), &
1505 diag_cs%G, h_diag, staggered_in_x, staggered_in_y, &
1506 diag%axes%mask3d, diag_cs%missing_value, field, remapped_field)
1508 if (
associated(diag%axes%mask3d))
then
1512 mask=diag%axes%mask3d)
1517 deallocate(remapped_field)
1519 elseif (diag%axes%needs_remapping)
then
1521 if (
present(mask))
then
1522 call mom_error(fatal,
"post_data_3d: no mask for regridded field.")
1526 allocate(remapped_field(
size(field,1),
size(field,2), diag%axes%nz))
1527 call diag_remap_do_remap(diag_cs%diag_remap_cs( &
1528 diag%axes%vertical_coordinate_number), &
1529 diag_cs%G, diag_cs%GV, h_diag, staggered_in_x, staggered_in_y, &
1530 diag%axes%mask3d, diag_cs%missing_value, field, remapped_field)
1532 if (
associated(diag%axes%mask3d))
then
1536 mask=diag%axes%mask3d)
1541 deallocate(remapped_field)
1543 elseif (diag%axes%needs_interpolating)
then
1545 if (
present(mask))
then
1546 call mom_error(fatal,
"post_data_3d: no mask for regridded field.")
1550 allocate(remapped_field(
size(field,1),
size(field,2), diag%axes%nz+1))
1551 call vertically_interpolate_diag_field(diag_cs%diag_remap_cs( &
1552 diag%axes%vertical_coordinate_number), &
1553 diag_cs%G, h_diag, staggered_in_x, staggered_in_y, &
1554 diag%axes%mask3d, diag_cs%missing_value, field, remapped_field)
1556 if (
associated(diag%axes%mask3d))
then
1560 mask=diag%axes%mask3d)
1565 deallocate(remapped_field)
1580 real,
target,
intent(in) :: field(:,:,:)
1582 logical,
optional,
intent(in) :: is_static
1583 real,
optional,
target,
intent(in) :: mask(:,:,:)
1586 real,
dimension(:,:,:),
pointer :: locfield
1587 real,
dimension(:,:,:),
pointer :: locmask
1588 character(len=300) :: mesg
1590 logical :: staggered_in_x, staggered_in_y
1592 integer :: cszi, cszj, dszi, dszj
1593 integer :: isv, iev, jsv, jev, ks, ke, i, j, k, isv_c, jsv_c, isv_o,jsv_o
1595 real,
dimension(:,:,:),
allocatable,
target :: locfield_dsamp
1596 real,
dimension(:,:,:),
allocatable,
target :: locmask_dsamp
1601 is_stat = .false. ;
if (
present(is_static)) is_stat = is_static
1608 isv = diag_cs%is ; iev = diag_cs%ie ; jsv = diag_cs%js ; jev = diag_cs%je
1610 cszi = (diag_cs%ie-diag_cs%is) +1 ; dszi = (diag_cs%ied-diag_cs%isd) +1
1611 cszj = (diag_cs%je-diag_cs%js) +1 ; dszj = (diag_cs%jed-diag_cs%jsd) +1
1612 if (
size(field,1) == dszi )
then
1613 isv = diag_cs%is ; iev = diag_cs%ie
1614 elseif (
size(field,1) == dszi + 1 )
then
1615 isv = diag_cs%is ; iev = diag_cs%ie+1
1616 elseif (
size(field,1) == cszi)
then
1617 isv = 1 ; iev = cszi
1618 elseif (
size(field,1) == cszi + 1 )
then
1619 isv = 1 ; iev = cszi+1
1621 write (mesg,*)
" peculiar size ",
size(field,1),
" in i-direction\n"//&
1622 "does not match one of ", cszi, cszi+1, dszi, dszi+1
1623 call mom_error(fatal,
"post_data_3d_low: "//trim(diag%debug_str)//trim(mesg))
1626 if (
size(field,2) == dszj )
then
1627 jsv = diag_cs%js ; jev = diag_cs%je
1628 elseif (
size(field,2) == dszj + 1 )
then
1629 jsv = diag_cs%js ; jev = diag_cs%je+1
1630 elseif (
size(field,2) == cszj )
then
1631 jsv = 1 ; jev = cszj
1632 elseif (
size(field,2) == cszj+1 )
then
1633 jsv = 1 ; jev = cszj+1
1635 write (mesg,*)
" peculiar size ",
size(field,2),
" in j-direction\n"//&
1636 "does not match one of ", cszj, cszj+1, dszj, dszj+1
1637 call mom_error(fatal,
"post_data_3d_low: "//trim(diag%debug_str)//trim(mesg))
1640 ks = lbound(field,3) ; ke = ubound(field,3)
1641 if ((diag%conversion_factor /= 0.) .and. (diag%conversion_factor /= 1.))
then
1642 allocate( locfield( lbound(field,1):ubound(field,1), lbound(field,2):ubound(field,2), ks:ke ) )
1645 isv_c = isv ; jsv_c = jsv
1646 if (diag%fms_xyave_diag_id>0)
then
1647 staggered_in_x = diag%axes%is_u_point .or. diag%axes%is_q_point
1648 staggered_in_y = diag%axes%is_v_point .or. diag%axes%is_q_point
1650 if (staggered_in_x) isv_c = iev - (diag_cs%ie - diag_cs%is) - 1
1651 if (staggered_in_y) jsv_c = jev - (diag_cs%je - diag_cs%js) - 1
1652 if (isv_c < lbound(locfield,1))
call mom_error(fatal, &
1653 "It is an error to average a staggered diagnostic field that does not "//&
1654 "have i-direction space to represent the symmetric computational domain.")
1655 if (jsv_c < lbound(locfield,2))
call mom_error(fatal, &
1656 "It is an error to average a staggered diagnostic field that does not "//&
1657 "have j-direction space to represent the symmetric computational domain.")
1660 do k=ks,ke ;
do j=jsv,jev ;
do i=isv,iev
1661 if (field(i,j,k) == diag_cs%missing_value)
then
1662 locfield(i,j,k) = diag_cs%missing_value
1664 locfield(i,j,k) = field(i,j,k) * diag%conversion_factor
1666 enddo ;
enddo ;
enddo
1671 if (
present(mask))
then
1673 elseif(
associated(diag%axes%mask3d))
then
1674 locmask => diag%axes%mask3d
1678 if(.NOT. is_stat) dl = diag%axes%downsample_level
1681 isv_o=isv ; jsv_o=jsv
1683 if ((diag%conversion_factor /= 0.) .and. (diag%conversion_factor /= 1.))
deallocate( locfield )
1684 locfield => locfield_dsamp
1685 if (
present(mask))
then
1686 call downsample_field_3d(locmask, locmask_dsamp, dl,
msk, locmask, diag_cs,diag,isv_o,jsv_o,isv,iev,jsv,jev)
1687 locmask => locmask_dsamp
1688 elseif(
associated(diag%axes%dsamp(dl)%mask3d))
then
1689 locmask => diag%axes%dsamp(dl)%mask3d
1693 if (diag%fms_diag_id>0)
then
1694 if (diag_cs%diag_as_chksum)
then
1695 if (diag%axes%is_h_point)
then
1696 call hchksum(locfield, diag%debug_str, diag_cs%G%HI, &
1697 logunit=diag_cs%chksum_iounit)
1698 else if (diag%axes%is_u_point)
then
1699 call uchksum(locfield, diag%debug_str, diag_cs%G%HI, &
1700 logunit=diag_cs%chksum_iounit)
1701 else if (diag%axes%is_v_point)
then
1702 call vchksum(locfield, diag%debug_str, diag_cs%G%HI, &
1703 logunit=diag_cs%chksum_iounit)
1704 else if (diag%axes%is_q_point)
then
1705 call bchksum(locfield, diag%debug_str, diag_cs%G%HI, &
1706 logunit=diag_cs%chksum_iounit)
1708 call mom_error(fatal,
"post_data_3d_low: unknown axis type.")
1712 if (
present(mask))
then
1713 call assert(
size(locfield) ==
size(locmask), &
1714 'post_data_3d_low is_stat: mask size mismatch: '//diag%debug_str)
1715 used = send_data(diag%fms_diag_id, locfield, &
1716 is_in=isv, js_in=jsv, ie_in=iev, je_in=jev, rmask=locmask)
1721 used = send_data(diag%fms_diag_id, locfield, &
1722 is_in=isv, js_in=jsv, ie_in=iev, je_in=jev)
1724 elseif (diag_cs%ave_enabled)
then
1725 if (
associated(locmask))
then
1726 call assert(
size(locfield) ==
size(locmask), &
1727 'post_data_3d_low: mask size mismatch: '//diag%debug_str)
1728 used = send_data(diag%fms_diag_id, locfield, diag_cs%time_end, &
1729 is_in=isv, js_in=jsv, ie_in=iev, je_in=jev, &
1730 weight=diag_cs%time_int, rmask=locmask)
1732 used = send_data(diag%fms_diag_id, locfield, diag_cs%time_end, &
1733 is_in=isv, js_in=jsv, ie_in=iev, je_in=jev, &
1734 weight=diag_cs%time_int)
1740 if (diag%fms_xyave_diag_id>0)
then
1744 if ((diag%conversion_factor /= 0.) .and. (diag%conversion_factor /= 1.) .and. dl<2) &
1745 deallocate( locfield )
1752 real,
target,
intent(in) :: field(:,:,:)
1755 real,
dimension(size(field,3)) :: averaged_field
1756 logical,
dimension(size(field,3)) :: averaged_mask
1757 logical :: staggered_in_x, staggered_in_y, used
1758 integer :: nz, remap_nz, coord
1760 if (.not. diag_cs%ave_enabled)
then
1764 staggered_in_x = diag%axes%is_u_point .or. diag%axes%is_q_point
1765 staggered_in_y = diag%axes%is_v_point .or. diag%axes%is_q_point
1767 if (diag%axes%is_native)
then
1769 staggered_in_x, staggered_in_y, &
1770 diag%axes%is_layer, diag%v_extensive, &
1771 diag_cs%missing_value, field, &
1772 averaged_field, averaged_mask)
1775 coord = diag%axes%vertical_coordinate_number
1776 remap_nz = diag_cs%diag_remap_cs(coord)%nz
1778 call assert(diag_cs%diag_remap_cs(coord)%initialized, &
1779 'post_xy_average: remap_cs not initialized.')
1781 call assert(implies(diag%axes%is_layer, nz == remap_nz), &
1782 'post_xy_average: layer field dimension mismatch.')
1783 call assert(implies(.not. diag%axes%is_layer, nz == remap_nz+1), &
1784 'post_xy_average: interface field dimension mismatch.')
1787 diag_cs%diag_remap_cs(coord)%h, &
1788 staggered_in_x, staggered_in_y, &
1789 diag%axes%is_layer, diag%v_extensive, &
1790 diag_cs%missing_value, field, &
1791 averaged_field, averaged_mask)
1794 if (diag_cs%diag_as_chksum)
then
1795 call zchksum(averaged_field, trim(diag%debug_str)//
'_xyave', &
1796 logunit=diag_cs%chksum_iounit)
1798 used = send_data(diag%fms_xyave_diag_id, averaged_field, diag_cs%time_end, &
1799 weight=diag_cs%time_int, mask=averaged_mask)
1805 real,
intent(in) :: time_int_in
1807 type(time_type),
intent(in) :: time_end_in
1808 type(
diag_ctrl),
intent(inout) :: diag_cs
1813 diag_cs%time_int = time_int_in
1814 diag_cs%time_end = time_end_in
1815 diag_cs%ave_enabled = .true.
1820 real,
intent(in) :: time_int
1822 type(time_type),
intent(in) :: time_end
1823 type(
diag_ctrl),
intent(inout) :: diag_cs
1824 real,
optional,
intent(in) :: t_to_s
1827 if (
present(t_to_s))
then
1828 diag_cs%time_int = time_int*t_to_s
1829 elseif (
associated(diag_cs%US))
then
1830 diag_cs%time_int = time_int*diag_cs%US%T_to_s
1832 diag_cs%time_int = time_int
1834 diag_cs%time_end = time_end
1835 diag_cs%ave_enabled = .true.
1842 diag_cs%time_int = 0.0
1843 diag_cs%ave_enabled = .false.
1851 real,
optional,
intent(out) :: time_int
1852 type(time_type),
optional,
intent(out) :: time_end
1855 if (
present(time_int)) time_int = diag_cs%time_int
1856 if (
present(time_end)) time_end = diag_cs%time_end
1874 long_name, units, missing_value, range, mask_variant, standard_name, &
1875 verbose, do_not_log, err_msg, interp_method, tile_count, cmor_field_name, &
1876 cmor_long_name, cmor_units, cmor_standard_name, cell_methods, &
1877 x_cell_method, y_cell_method, v_cell_method, conversion, v_extensive)
1878 character(len=*),
intent(in) :: module_name
1880 character(len=*),
intent(in) :: field_name
1881 type(
axes_grp),
target,
intent(in) :: axes_in
1883 type(time_type),
intent(in) :: init_time
1884 character(len=*),
optional,
intent(in) :: long_name
1885 character(len=*),
optional,
intent(in) :: units
1886 character(len=*),
optional,
intent(in) :: standard_name
1887 real,
optional,
intent(in) :: missing_value
1888 real,
optional,
intent(in) :: range(2)
1889 logical,
optional,
intent(in) :: mask_variant
1891 logical,
optional,
intent(in) :: verbose
1892 logical,
optional,
intent(in) :: do_not_log
1893 character(len=*),
optional,
intent(out):: err_msg
1895 character(len=*),
optional,
intent(in) :: interp_method
1897 integer,
optional,
intent(in) :: tile_count
1898 character(len=*),
optional,
intent(in) :: cmor_field_name
1899 character(len=*),
optional,
intent(in) :: cmor_long_name
1900 character(len=*),
optional,
intent(in) :: cmor_units
1901 character(len=*),
optional,
intent(in) :: cmor_standard_name
1902 character(len=*),
optional,
intent(in) :: cell_methods
1906 character(len=*),
optional,
intent(in) :: x_cell_method
1908 character(len=*),
optional,
intent(in) :: y_cell_method
1910 character(len=*),
optional,
intent(in) :: v_cell_method
1912 real,
optional,
intent(in) :: conversion
1913 logical,
optional,
intent(in) :: v_extensive
1916 real :: mom_missing_value
1917 type(
diag_ctrl),
pointer :: diag_cs => null()
1918 type(
axes_grp),
pointer :: remap_axes => null()
1919 type(
axes_grp),
pointer :: axes => null()
1920 integer :: dm_id, i, dl
1921 character(len=256) :: new_module_name
1925 mom_missing_value = axes%diag_cs%missing_value
1926 if (
present(missing_value)) mom_missing_value = missing_value
1928 diag_cs => axes%diag_cs
1931 if (axes_in%id == diag_cs%axesTL%id)
then
1932 axes => diag_cs%axesTL
1933 elseif (axes_in%id == diag_cs%axesBL%id)
then
1934 axes => diag_cs%axesBL
1935 elseif (axes_in%id == diag_cs%axesCuL%id )
then
1936 axes => diag_cs%axesCuL
1937 elseif (axes_in%id == diag_cs%axesCvL%id)
then
1938 axes => diag_cs%axesCvL
1939 elseif (axes_in%id == diag_cs%axesTi%id)
then
1940 axes => diag_cs%axesTi
1941 elseif (axes_in%id == diag_cs%axesBi%id)
then
1942 axes => diag_cs%axesBi
1943 elseif (axes_in%id == diag_cs%axesCui%id )
then
1944 axes => diag_cs%axesCui
1945 elseif (axes_in%id == diag_cs%axesCvi%id)
then
1946 axes => diag_cs%axesCvi
1951 init_time, long_name=long_name, units=units, missing_value=mom_missing_value, &
1952 range=range, mask_variant=mask_variant, standard_name=standard_name, &
1953 verbose=verbose, do_not_log=do_not_log, err_msg=err_msg, &
1954 interp_method=interp_method, tile_count=tile_count, &
1955 cmor_field_name=cmor_field_name, cmor_long_name=cmor_long_name, &
1956 cmor_units=cmor_units, cmor_standard_name=cmor_standard_name, &
1957 cell_methods=cell_methods, x_cell_method=x_cell_method, &
1958 y_cell_method=y_cell_method, v_cell_method=v_cell_method, &
1959 conversion=conversion, v_extensive=v_extensive)
1962 do i=1,diag_cs%num_diag_coords
1963 new_module_name = trim(module_name)//
'_'//trim(diag_cs%diag_remap_cs(i)%diag_module_suffix)
1966 if (axes_in%rank == 3)
then
1967 remap_axes => null()
1968 if ((axes_in%id == diag_cs%axesTL%id))
then
1969 remap_axes => diag_cs%remap_axesTL(i)
1970 elseif (axes_in%id == diag_cs%axesBL%id)
then
1971 remap_axes => diag_cs%remap_axesBL(i)
1972 elseif (axes_in%id == diag_cs%axesCuL%id )
then
1973 remap_axes => diag_cs%remap_axesCuL(i)
1974 elseif (axes_in%id == diag_cs%axesCvL%id)
then
1975 remap_axes => diag_cs%remap_axesCvL(i)
1976 elseif (axes_in%id == diag_cs%axesTi%id)
then
1977 remap_axes => diag_cs%remap_axesTi(i)
1978 elseif (axes_in%id == diag_cs%axesBi%id)
then
1979 remap_axes => diag_cs%remap_axesBi(i)
1980 elseif (axes_in%id == diag_cs%axesCui%id )
then
1981 remap_axes => diag_cs%remap_axesCui(i)
1982 elseif (axes_in%id == diag_cs%axesCvi%id)
then
1983 remap_axes => diag_cs%remap_axesCvi(i)
1988 if (
associated(remap_axes))
then
1989 if (remap_axes%needs_remapping .or. remap_axes%needs_interpolating)
then
1991 init_time, long_name=long_name, units=units, missing_value=mom_missing_value, &
1992 range=range, mask_variant=mask_variant, standard_name=standard_name, &
1993 verbose=verbose, do_not_log=do_not_log, err_msg=err_msg, &
1994 interp_method=interp_method, tile_count=tile_count, &
1995 cmor_field_name=cmor_field_name, cmor_long_name=cmor_long_name, &
1996 cmor_units=cmor_units, cmor_standard_name=cmor_standard_name, &
1997 cell_methods=cell_methods, x_cell_method=x_cell_method, &
1998 y_cell_method=y_cell_method, v_cell_method=v_cell_method, &
1999 conversion=conversion, v_extensive=v_extensive)
2001 call diag_remap_set_active(diag_cs%diag_remap_cs(i))
2009 do dl=2,max_dsamp_lev
2011 if (diag_cs%diag_as_chksum) cycle
2013 new_module_name = trim(module_name)//
'_d2'
2015 if (axes_in%rank == 3 .or. axes_in%rank == 2 )
then
2017 if (axes_in%id == diag_cs%axesTL%id)
then
2018 axes => diag_cs%dsamp(dl)%axesTL
2019 elseif (axes_in%id == diag_cs%axesBL%id)
then
2020 axes => diag_cs%dsamp(dl)%axesBL
2021 elseif (axes_in%id == diag_cs%axesCuL%id )
then
2022 axes => diag_cs%dsamp(dl)%axesCuL
2023 elseif (axes_in%id == diag_cs%axesCvL%id)
then
2024 axes => diag_cs%dsamp(dl)%axesCvL
2025 elseif (axes_in%id == diag_cs%axesTi%id)
then
2026 axes => diag_cs%dsamp(dl)%axesTi
2027 elseif (axes_in%id == diag_cs%axesBi%id)
then
2028 axes => diag_cs%dsamp(dl)%axesBi
2029 elseif (axes_in%id == diag_cs%axesCui%id )
then
2030 axes => diag_cs%dsamp(dl)%axesCui
2031 elseif (axes_in%id == diag_cs%axesCvi%id)
then
2032 axes => diag_cs%dsamp(dl)%axesCvi
2033 elseif (axes_in%id == diag_cs%axesT1%id)
then
2034 axes => diag_cs%dsamp(dl)%axesT1
2035 elseif (axes_in%id == diag_cs%axesB1%id)
then
2036 axes => diag_cs%dsamp(dl)%axesB1
2037 elseif (axes_in%id == diag_cs%axesCu1%id )
then
2038 axes => diag_cs%dsamp(dl)%axesCu1
2039 elseif (axes_in%id == diag_cs%axesCv1%id)
then
2040 axes => diag_cs%dsamp(dl)%axesCv1
2043 call mom_error(warning,
"register_diag_field: Could not find a proper axes for " &
2044 //trim( new_module_name)//
"-"//trim(field_name))
2048 if (
associated(axes))
then
2050 init_time, long_name=long_name, units=units, missing_value=mom_missing_value, &
2051 range=range, mask_variant=mask_variant, standard_name=standard_name, &
2052 verbose=verbose, do_not_log=do_not_log, err_msg=err_msg, &
2053 interp_method=interp_method, tile_count=tile_count, &
2054 cmor_field_name=cmor_field_name, cmor_long_name=cmor_long_name, &
2055 cmor_units=cmor_units, cmor_standard_name=cmor_standard_name, &
2056 cell_methods=cell_methods, x_cell_method=x_cell_method, &
2057 y_cell_method=y_cell_method, v_cell_method=v_cell_method, &
2058 conversion=conversion, v_extensive=v_extensive)
2062 do i=1,diag_cs%num_diag_coords
2063 new_module_name = trim(module_name)//
'_'//trim(diag_cs%diag_remap_cs(i)%diag_module_suffix)//
'_d2'
2066 if (axes_in%rank == 3)
then
2067 remap_axes => null()
2068 if ((axes_in%id == diag_cs%axesTL%id))
then
2069 remap_axes => diag_cs%dsamp(dl)%remap_axesTL(i)
2070 elseif (axes_in%id == diag_cs%axesBL%id)
then
2071 remap_axes => diag_cs%dsamp(dl)%remap_axesBL(i)
2072 elseif (axes_in%id == diag_cs%axesCuL%id )
then
2073 remap_axes => diag_cs%dsamp(dl)%remap_axesCuL(i)
2074 elseif (axes_in%id == diag_cs%axesCvL%id)
then
2075 remap_axes => diag_cs%dsamp(dl)%remap_axesCvL(i)
2076 elseif (axes_in%id == diag_cs%axesTi%id)
then
2077 remap_axes => diag_cs%dsamp(dl)%remap_axesTi(i)
2078 elseif (axes_in%id == diag_cs%axesBi%id)
then
2079 remap_axes => diag_cs%dsamp(dl)%remap_axesBi(i)
2080 elseif (axes_in%id == diag_cs%axesCui%id )
then
2081 remap_axes => diag_cs%dsamp(dl)%remap_axesCui(i)
2082 elseif (axes_in%id == diag_cs%axesCvi%id)
then
2083 remap_axes => diag_cs%dsamp(dl)%remap_axesCvi(i)
2089 if (
associated(remap_axes))
then
2090 if (remap_axes%needs_remapping .or. remap_axes%needs_interpolating)
then
2092 init_time, long_name=long_name, units=units, missing_value=mom_missing_value, &
2093 range=range, mask_variant=mask_variant, standard_name=standard_name, &
2094 verbose=verbose, do_not_log=do_not_log, err_msg=err_msg, &
2095 interp_method=interp_method, tile_count=tile_count, &
2096 cmor_field_name=cmor_field_name, cmor_long_name=cmor_long_name, &
2097 cmor_units=cmor_units, cmor_standard_name=cmor_standard_name, &
2098 cell_methods=cell_methods, x_cell_method=x_cell_method, &
2099 y_cell_method=y_cell_method, v_cell_method=v_cell_method, &
2100 conversion=conversion, v_extensive=v_extensive)
2102 call diag_remap_set_active(diag_cs%diag_remap_cs(i))
2117 long_name, units, missing_value, range, mask_variant, standard_name, &
2118 verbose, do_not_log, err_msg, interp_method, tile_count, cmor_field_name, &
2119 cmor_long_name, cmor_units, cmor_standard_name, cell_methods, &
2120 x_cell_method, y_cell_method, v_cell_method, conversion, v_extensive)
2121 integer,
intent(inout) :: dm_id
2122 character(len=*),
intent(in) :: module_name
2123 character(len=*),
intent(in) :: field_name
2124 type(
axes_grp),
target,
intent(in) :: axes
2126 type(time_type),
intent(in) :: init_time
2127 character(len=*),
optional,
intent(in) :: long_name
2128 character(len=*),
optional,
intent(in) :: units
2129 character(len=*),
optional,
intent(in) :: standard_name
2130 real,
optional,
intent(in) :: missing_value
2131 real,
optional,
intent(in) :: range(2)
2132 logical,
optional,
intent(in) :: mask_variant
2134 logical,
optional,
intent(in) :: verbose
2135 logical,
optional,
intent(in) :: do_not_log
2136 character(len=*),
optional,
intent(out):: err_msg
2138 character(len=*),
optional,
intent(in) :: interp_method
2140 integer,
optional,
intent(in) :: tile_count
2141 character(len=*),
optional,
intent(in) :: cmor_field_name
2142 character(len=*),
optional,
intent(in) :: cmor_long_name
2143 character(len=*),
optional,
intent(in) :: cmor_units
2144 character(len=*),
optional,
intent(in) :: cmor_standard_name
2145 character(len=*),
optional,
intent(in) :: cell_methods
2149 character(len=*),
optional,
intent(in) :: x_cell_method
2151 character(len=*),
optional,
intent(in) :: y_cell_method
2153 character(len=*),
optional,
intent(in) :: v_cell_method
2155 real,
optional,
intent(in) :: conversion
2156 logical,
optional,
intent(in) :: v_extensive
2159 real :: mom_missing_value
2160 type(
diag_ctrl),
pointer :: diag_cs => null()
2161 type(
diag_type),
pointer :: this_diag => null()
2162 integer :: fms_id, fms_xyave_id
2163 character(len=256) :: posted_cmor_units, posted_cmor_standard_name, posted_cmor_long_name, cm_string, msg
2165 mom_missing_value = axes%diag_cs%missing_value
2166 if (
present(missing_value)) mom_missing_value = missing_value
2169 diag_cs => axes%diag_cs
2173 long_name=long_name, units=units, missing_value=mom_missing_value, &
2174 range=range, mask_variant=mask_variant, standard_name=standard_name, &
2175 verbose=verbose, do_not_log=do_not_log, err_msg=err_msg, &
2176 interp_method=interp_method, tile_count=tile_count)
2177 if (.not. diag_cs%diag_as_chksum) &
2179 x_cell_method, y_cell_method, v_cell_method, &
2180 v_extensive=v_extensive)
2181 if (
is_root_pe() .and. diag_cs%available_diag_doc_unit > 0)
then
2183 if (
present(cmor_field_name)) msg =
'CMOR equivalent is "'//trim(cmor_field_name)//
'"'
2185 msg, diag_cs, long_name, units, standard_name)
2188 fms_xyave_id = diag_field_not_found
2189 if (
associated(axes%xyave_axes))
then
2191 axes%xyave_axes, init_time, &
2192 long_name=long_name, units=units, missing_value=mom_missing_value, &
2193 range=range, mask_variant=mask_variant, standard_name=standard_name, &
2194 verbose=verbose, do_not_log=do_not_log, err_msg=err_msg, &
2195 interp_method=interp_method, tile_count=tile_count)
2196 if (.not. diag_cs%diag_as_chksum) &
2198 cell_methods, v_cell_method, v_extensive=v_extensive)
2199 if (
is_root_pe() .and. diag_cs%available_diag_doc_unit > 0)
then
2201 if (
present(cmor_field_name)) msg =
'CMOR equivalent is "'//trim(cmor_field_name)//
'_xyave"'
2202 call log_available_diag(fms_xyave_id>0, module_name, trim(field_name)//
'_xyave', cm_string, &
2203 msg, diag_cs, long_name, units, standard_name)
2207 if (fms_id /= diag_field_not_found .or. fms_xyave_id /= diag_field_not_found)
then
2208 call add_diag_to_list(diag_cs, dm_id, fms_id, this_diag, axes, module_name, field_name, msg)
2209 this_diag%fms_xyave_diag_id = fms_xyave_id
2211 call add_xyz_method(this_diag, axes, x_cell_method, y_cell_method, v_cell_method, v_extensive)
2212 if (
present(v_extensive)) this_diag%v_extensive = v_extensive
2213 if (
present(conversion)) this_diag%conversion_factor = conversion
2218 if (
present(cmor_field_name) .and. .not. diag_cs%diag_as_chksum)
then
2220 posted_cmor_units =
"not provided"
2221 posted_cmor_standard_name =
"not provided"
2222 posted_cmor_long_name =
"not provided"
2226 if (
present(units)) posted_cmor_units = units
2227 if (
present(standard_name)) posted_cmor_standard_name = standard_name
2228 if (
present(long_name)) posted_cmor_long_name = long_name
2231 if (
present(cmor_units)) posted_cmor_units = cmor_units
2232 if (
present(cmor_standard_name)) posted_cmor_standard_name = cmor_standard_name
2233 if (
present(cmor_long_name)) posted_cmor_long_name = cmor_long_name
2236 long_name=trim(posted_cmor_long_name), units=trim(posted_cmor_units), &
2237 missing_value=mom_missing_value, range=range, mask_variant=mask_variant, &
2238 standard_name=trim(posted_cmor_standard_name), verbose=verbose, do_not_log=do_not_log, &
2239 err_msg=err_msg, interp_method=interp_method, tile_count=tile_count)
2241 cell_methods, x_cell_method, y_cell_method, v_cell_method, &
2242 v_extensive=v_extensive)
2243 if (
is_root_pe() .and. diag_cs%available_diag_doc_unit > 0)
then
2244 msg =
'native name is "'//trim(field_name)//
'"'
2246 msg, diag_cs, posted_cmor_long_name, posted_cmor_units, &
2247 posted_cmor_standard_name)
2250 fms_xyave_id = diag_field_not_found
2251 if (
associated(axes%xyave_axes))
then
2253 axes%xyave_axes, init_time, &
2254 long_name=trim(posted_cmor_long_name), units=trim(posted_cmor_units), &
2255 missing_value=mom_missing_value, range=range, mask_variant=mask_variant, &
2256 standard_name=trim(posted_cmor_standard_name), verbose=verbose, do_not_log=do_not_log, &
2257 err_msg=err_msg, interp_method=interp_method, tile_count=tile_count)
2259 cell_methods, v_cell_method, v_extensive=v_extensive)
2260 if (
is_root_pe() .and. diag_cs%available_diag_doc_unit > 0)
then
2261 msg =
'native name is "'//trim(field_name)//
'_xyave"'
2262 call log_available_diag(fms_xyave_id>0, module_name, trim(cmor_field_name)//
'_xyave', &
2263 cm_string, msg, diag_cs, posted_cmor_long_name, posted_cmor_units, &
2264 posted_cmor_standard_name)
2268 if (fms_id /= diag_field_not_found .or. fms_xyave_id /= diag_field_not_found)
then
2269 call add_diag_to_list(diag_cs, dm_id, fms_id, this_diag, axes, module_name, field_name, msg)
2270 this_diag%fms_xyave_diag_id = fms_xyave_id
2272 call add_xyz_method(this_diag, axes, x_cell_method, y_cell_method, v_cell_method, v_extensive)
2273 if (
present(v_extensive)) this_diag%v_extensive = v_extensive
2274 if (
present(conversion)) this_diag%conversion_factor = conversion
2284 long_name, units, missing_value, range, mask_variant, standard_name, &
2285 verbose, do_not_log, err_msg, interp_method, tile_count)
2286 character(len=*),
intent(in) :: module_name
2288 character(len=*),
intent(in) :: field_name
2289 type(
axes_grp),
target,
intent(in) :: axes
2291 type(time_type),
intent(in) :: init_time
2292 character(len=*),
optional,
intent(in) :: long_name
2293 character(len=*),
optional,
intent(in) :: units
2294 character(len=*),
optional,
intent(in) :: standard_name
2295 real,
optional,
intent(in) :: missing_value
2296 real,
optional,
intent(in) :: range(2)
2297 logical,
optional,
intent(in) :: mask_variant
2299 logical,
optional,
intent(in) :: verbose
2300 logical,
optional,
intent(in) :: do_not_log
2302 character(len=*),
optional,
intent(out):: err_msg
2304 character(len=*),
optional,
intent(in) :: interp_method
2306 integer,
optional,
intent(in) :: tile_count
2308 integer :: fms_id, area_id, volume_id
2311 area_id = axes%id_area
2312 volume_id = axes%id_volume
2315 if (axes%diag_cs%diag_as_chksum)
then
2316 fms_id = axes%diag_cs%num_chksum_diags + 1
2317 axes%diag_cs%num_chksum_diags = fms_id
2318 else if (
present(interp_method) .or. axes%is_h_point)
then
2321 if (volume_id>0)
then
2323 init_time, long_name=long_name, units=units, missing_value=missing_value, &
2324 range=range, mask_variant=mask_variant, standard_name=standard_name, &
2325 verbose=verbose, do_not_log=do_not_log, err_msg=err_msg, &
2326 interp_method=interp_method, tile_count=tile_count, area=area_id, volume=volume_id)
2329 init_time, long_name=long_name, units=units, missing_value=missing_value, &
2330 range=range, mask_variant=mask_variant, standard_name=standard_name, &
2331 verbose=verbose, do_not_log=do_not_log, err_msg=err_msg, &
2332 interp_method=interp_method, tile_count=tile_count, area=area_id)
2335 if (volume_id>0)
then
2337 init_time, long_name=long_name, units=units, missing_value=missing_value, &
2338 range=range, mask_variant=mask_variant, standard_name=standard_name, &
2339 verbose=verbose, do_not_log=do_not_log, err_msg=err_msg, &
2340 interp_method=interp_method, tile_count=tile_count, volume=volume_id)
2343 init_time, long_name=long_name, units=units, missing_value=missing_value, &
2344 range=range, mask_variant=mask_variant, standard_name=standard_name, &
2345 verbose=verbose, do_not_log=do_not_log, err_msg=err_msg, &
2346 interp_method=interp_method, tile_count=tile_count)
2352 if (volume_id>0)
then
2354 init_time, long_name=long_name, units=units, missing_value=missing_value, &
2355 range=range, mask_variant=mask_variant, standard_name=standard_name, &
2356 verbose=verbose, do_not_log=do_not_log, err_msg=err_msg, &
2357 interp_method=
'none', tile_count=tile_count, area=area_id, volume=volume_id)
2360 init_time, long_name=long_name, units=units, missing_value=missing_value, &
2361 range=range, mask_variant=mask_variant, standard_name=standard_name, &
2362 verbose=verbose, do_not_log=do_not_log, err_msg=err_msg, &
2363 interp_method=
'none', tile_count=tile_count, area=area_id)
2366 if (volume_id>0)
then
2368 init_time, long_name=long_name, units=units, missing_value=missing_value, &
2369 range=range, mask_variant=mask_variant, standard_name=standard_name, &
2370 verbose=verbose, do_not_log=do_not_log, err_msg=err_msg, &
2371 interp_method=
'none', tile_count=tile_count, volume=volume_id)
2374 init_time, long_name=long_name, units=units, missing_value=missing_value, &
2375 range=range, mask_variant=mask_variant, standard_name=standard_name, &
2376 verbose=verbose, do_not_log=do_not_log, err_msg=err_msg, &
2377 interp_method=
'none', tile_count=tile_count)
2387 subroutine add_diag_to_list(diag_cs, dm_id, fms_id, this_diag, axes, module_name, field_name, msg)
2389 integer,
intent(inout) :: dm_id
2390 integer,
intent(in) :: fms_id
2392 type(
axes_grp),
target,
intent(in) :: axes
2394 character(len=*),
intent(in) :: module_name
2396 character(len=*),
intent(in) :: field_name
2397 character(len=*),
intent(in) :: msg
2403 call assert(
associated(this_diag), trim(msg)//
': diag_type allocation failed')
2405 this_diag%fms_diag_id = fms_id
2406 this_diag%debug_str = trim(module_name)//
"-"//trim(field_name)
2407 this_diag%axes => axes
2413 subroutine add_xyz_method(diag, axes, x_cell_method, y_cell_method, v_cell_method, v_extensive)
2417 character(len=*),
optional,
intent(in) :: x_cell_method
2419 character(len=*),
optional,
intent(in) :: y_cell_method
2421 character(len=*),
optional,
intent(in) :: v_cell_method
2423 logical,
optional,
intent(in) :: v_extensive
2425 integer :: xyz_method
2426 character(len=9) :: mstr
2437 mstr = diag%axes%v_cell_method
2438 if (
present(v_extensive))
then
2439 if (
present(v_cell_method))
call mom_error(fatal,
"attach_cell_methods: " // &
2440 'Vertical cell method was specified along with the vertically extensive flag.')
2441 if(v_extensive)
then
2446 elseif (
present(v_cell_method))
then
2447 mstr = v_cell_method
2449 if (trim(mstr)==
'sum')
then
2450 xyz_method = xyz_method + 1
2451 elseif (trim(mstr)==
'mean')
then
2452 xyz_method = xyz_method + 2
2455 mstr = diag%axes%y_cell_method
2456 if (
present(y_cell_method)) mstr = y_cell_method
2457 if (trim(mstr)==
'sum')
then
2458 xyz_method = xyz_method + 10
2459 elseif (trim(mstr)==
'mean')
then
2460 xyz_method = xyz_method + 20
2463 mstr = diag%axes%x_cell_method
2464 if (
present(x_cell_method)) mstr = x_cell_method
2465 if (trim(mstr)==
'sum')
then
2466 xyz_method = xyz_method + 100
2467 elseif (trim(mstr)==
'mean')
then
2468 xyz_method = xyz_method + 200
2471 diag%xyz_method = xyz_method
2476 x_cell_method, y_cell_method, v_cell_method, v_extensive)
2477 integer,
intent(in) :: id
2480 character(len=*),
intent(out) :: ostring
2481 character(len=*),
optional,
intent(in) :: cell_methods
2485 character(len=*),
optional,
intent(in) :: x_cell_method
2487 character(len=*),
optional,
intent(in) :: y_cell_method
2489 character(len=*),
optional,
intent(in) :: v_cell_method
2491 logical,
optional,
intent(in) :: v_extensive
2494 character(len=9) :: axis_name
2495 logical :: x_mean, y_mean, x_sum, y_sum
2503 if (
present(cell_methods))
then
2504 if (
present(x_cell_method) .or.
present(y_cell_method) .or.
present(v_cell_method) &
2505 .or.
present(v_extensive))
then
2506 call mom_error(fatal,
"attach_cell_methods: " // &
2507 'Individual direction cell method was specified along with a "cell_methods" string.')
2509 if (len(trim(cell_methods))>0)
then
2510 call diag_field_add_attribute(id,
'cell_methods', trim(cell_methods))
2511 ostring = trim(cell_methods)
2514 if (
present(x_cell_method))
then
2515 if (len(trim(x_cell_method))>0)
then
2516 call get_diag_axis_name(axes%handles(1), axis_name)
2517 call diag_field_add_attribute(id,
'cell_methods', trim(axis_name)//
':'//trim(x_cell_method))
2518 ostring = trim(adjustl(ostring))//
' '//trim(axis_name)//
':'//trim(x_cell_method)
2519 if (trim(x_cell_method)==
'mean') x_mean=.true.
2520 if (trim(x_cell_method)==
'sum') x_sum=.true.
2523 if (len(trim(axes%x_cell_method))>0)
then
2524 call get_diag_axis_name(axes%handles(1), axis_name)
2525 call diag_field_add_attribute(id,
'cell_methods', trim(axis_name)//
':'//trim(axes%x_cell_method))
2526 ostring = trim(adjustl(ostring))//
' '//trim(axis_name)//
':'//trim(axes%x_cell_method)
2527 if (trim(axes%x_cell_method)==
'mean') x_mean=.true.
2528 if (trim(axes%x_cell_method)==
'sum') x_sum=.true.
2531 if (
present(y_cell_method))
then
2532 if (len(trim(y_cell_method))>0)
then
2533 call get_diag_axis_name(axes%handles(2), axis_name)
2534 call diag_field_add_attribute(id,
'cell_methods', trim(axis_name)//
':'//trim(y_cell_method))
2535 ostring = trim(adjustl(ostring))//
' '//trim(axis_name)//
':'//trim(y_cell_method)
2536 if (trim(y_cell_method)==
'mean') y_mean=.true.
2537 if (trim(y_cell_method)==
'sum') y_sum=.true.
2540 if (len(trim(axes%y_cell_method))>0)
then
2541 call get_diag_axis_name(axes%handles(2), axis_name)
2542 call diag_field_add_attribute(id,
'cell_methods', trim(axis_name)//
':'//trim(axes%y_cell_method))
2543 ostring = trim(adjustl(ostring))//
' '//trim(axis_name)//
':'//trim(axes%y_cell_method)
2544 if (trim(axes%y_cell_method)==
'mean') y_mean=.true.
2545 if (trim(axes%y_cell_method)==
'sum') y_sum=.true.
2548 if (
present(v_cell_method))
then
2549 if (
present(v_extensive))
call mom_error(fatal,
"attach_cell_methods: " // &
2550 'Vertical cell method was specified along with the vertically extensive flag.')
2551 if (len(trim(v_cell_method))>0)
then
2552 if (axes%rank==1)
then
2553 call get_diag_axis_name(axes%handles(1), axis_name)
2554 elseif (axes%rank==3)
then
2555 call get_diag_axis_name(axes%handles(3), axis_name)
2557 call diag_field_add_attribute(id,
'cell_methods', trim(axis_name)//
':'//trim(v_cell_method))
2558 ostring = trim(adjustl(ostring))//
' '//trim(axis_name)//
':'//trim(v_cell_method)
2560 elseif (
present(v_extensive))
then
2561 if(v_extensive)
then
2562 if (axes%rank==1)
then
2563 call get_diag_axis_name(axes%handles(1), axis_name)
2564 elseif (axes%rank==3)
then
2565 call get_diag_axis_name(axes%handles(3), axis_name)
2567 call diag_field_add_attribute(id,
'cell_methods', trim(axis_name)//
':sum')
2568 ostring = trim(adjustl(ostring))//
' '//trim(axis_name)//
':sum'
2571 if (len(trim(axes%v_cell_method))>0)
then
2572 if (axes%rank==1)
then
2573 call get_diag_axis_name(axes%handles(1), axis_name)
2574 elseif (axes%rank==3)
then
2575 call get_diag_axis_name(axes%handles(3), axis_name)
2577 call diag_field_add_attribute(id,
'cell_methods', trim(axis_name)//
':'//trim(axes%v_cell_method))
2578 ostring = trim(adjustl(ostring))//
' '//trim(axis_name)//
':'//trim(axes%v_cell_method)
2581 if (x_mean .and. y_mean)
then
2582 call diag_field_add_attribute(id,
'cell_methods',
'area:mean')
2583 ostring = trim(adjustl(ostring))//
' area:mean'
2584 elseif (x_sum .and. y_sum)
then
2585 call diag_field_add_attribute(id,
'cell_methods',
'area:sum')
2586 ostring = trim(adjustl(ostring))//
' area:sum'
2589 ostring = adjustl(ostring)
2593 long_name, units, missing_value, range, standard_name, &
2594 do_not_log, err_msg, interp_method, cmor_field_name, &
2595 cmor_long_name, cmor_units, cmor_standard_name)
2597 character(len=*),
intent(in) :: module_name
2599 character(len=*),
intent(in) :: field_name
2600 type(time_type),
intent(in) :: init_time
2601 type(
diag_ctrl),
intent(inout) :: diag_cs
2602 character(len=*),
optional,
intent(in) :: long_name
2603 character(len=*),
optional,
intent(in) :: units
2604 character(len=*),
optional,
intent(in) :: standard_name
2605 real,
optional,
intent(in) :: missing_value
2606 real,
optional,
intent(in) :: range(2)
2607 logical,
optional,
intent(in) :: do_not_log
2608 character(len=*),
optional,
intent(out):: err_msg
2610 character(len=*),
optional,
intent(in) :: interp_method
2612 character(len=*),
optional,
intent(in) :: cmor_field_name
2613 character(len=*),
optional,
intent(in) :: cmor_long_name
2614 character(len=*),
optional,
intent(in) :: cmor_units
2615 character(len=*),
optional,
intent(in) :: cmor_standard_name
2618 real :: mom_missing_value
2619 integer :: dm_id, fms_id
2620 type(
diag_type),
pointer :: diag => null(), cmor_diag => null()
2621 character(len=256) :: posted_cmor_units, posted_cmor_standard_name, posted_cmor_long_name
2623 mom_missing_value = diag_cs%missing_value
2624 if (
present(missing_value)) mom_missing_value = missing_value
2630 if (diag_cs%diag_as_chksum)
then
2631 fms_id = diag_cs%num_chksum_diags + 1
2632 diag_cs%num_chksum_diags = fms_id
2635 long_name=long_name, units=units, missing_value=mom_missing_value, &
2636 range=range, standard_name=standard_name, do_not_log=do_not_log, &
2640 if (fms_id /= diag_field_not_found)
then
2643 call assert(
associated(diag),
'register_scalar_field: diag allocation failed')
2644 diag%fms_diag_id = fms_id
2645 diag%debug_str = trim(module_name)//
"-"//trim(field_name)
2648 if (
present(cmor_field_name))
then
2650 posted_cmor_units =
"not provided"
2651 posted_cmor_standard_name =
"not provided"
2652 posted_cmor_long_name =
"not provided"
2656 if (
present(units)) posted_cmor_units = units
2657 if (
present(standard_name)) posted_cmor_standard_name = standard_name
2658 if (
present(long_name)) posted_cmor_long_name = long_name
2661 if (
present(cmor_units)) posted_cmor_units = cmor_units
2662 if (
present(cmor_standard_name)) posted_cmor_standard_name = cmor_standard_name
2663 if (
present(cmor_long_name)) posted_cmor_long_name = cmor_long_name
2666 long_name=trim(posted_cmor_long_name), units=trim(posted_cmor_units), &
2667 missing_value=mom_missing_value, range=range, &
2668 standard_name=trim(posted_cmor_standard_name), do_not_log=do_not_log, err_msg=err_msg)
2669 if (fms_id /= diag_field_not_found)
then
2670 if (dm_id == -1)
then
2674 cmor_diag%fms_diag_id = fms_id
2675 cmor_diag%debug_str = trim(module_name)//
"-"//trim(cmor_field_name)
2680 if (
is_root_pe() .and. diag_cs%available_diag_doc_unit > 0)
then
2681 call log_available_diag(
associated(diag), module_name, field_name,
'',
'', diag_cs, &
2682 long_name, units, standard_name)
2683 if (
present(cmor_field_name))
then
2685 '',
'', diag_cs, posted_cmor_long_name, posted_cmor_units, &
2686 posted_cmor_standard_name)
2696 long_name, units, missing_value, range, mask_variant, standard_name, &
2697 do_not_log, interp_method, tile_count, &
2698 cmor_field_name, cmor_long_name, cmor_units, cmor_standard_name, area, &
2699 x_cell_method, y_cell_method, area_cell_method, conversion)
2701 character(len=*),
intent(in) :: module_name
2703 character(len=*),
intent(in) :: field_name
2704 type(
axes_grp),
target,
intent(in) :: axes
2706 character(len=*),
optional,
intent(in) :: long_name
2707 character(len=*),
optional,
intent(in) :: units
2708 character(len=*),
optional,
intent(in) :: standard_name
2709 real,
optional,
intent(in) :: missing_value
2710 real,
optional,
intent(in) :: range(2)
2711 logical,
optional,
intent(in) :: mask_variant
2713 logical,
optional,
intent(in) :: do_not_log
2714 character(len=*),
optional,
intent(in) :: interp_method
2716 integer,
optional,
intent(in) :: tile_count
2717 character(len=*),
optional,
intent(in) :: cmor_field_name
2718 character(len=*),
optional,
intent(in) :: cmor_long_name
2719 character(len=*),
optional,
intent(in) :: cmor_units
2720 character(len=*),
optional,
intent(in) :: cmor_standard_name
2721 integer,
optional,
intent(in) :: area
2722 character(len=*),
optional,
intent(in) :: x_cell_method
2723 character(len=*),
optional,
intent(in) :: y_cell_method
2724 character(len=*),
optional,
intent(in) :: area_cell_method
2725 real,
optional,
intent(in) :: conversion
2728 real :: mom_missing_value
2729 type(
diag_ctrl),
pointer :: diag_cs => null()
2730 type(
diag_type),
pointer :: diag => null(), cmor_diag => null()
2731 integer :: dm_id, fms_id, cmor_id
2732 character(len=256) :: posted_cmor_units, posted_cmor_standard_name, posted_cmor_long_name
2733 character(len=9) :: axis_name
2735 mom_missing_value = axes%diag_cs%missing_value
2736 if (
present(missing_value)) mom_missing_value = missing_value
2738 diag_cs => axes%diag_cs
2743 if (diag_cs%diag_as_chksum)
then
2744 fms_id = diag_cs%num_chksum_diags + 1
2745 diag_cs%num_chksum_diags = fms_id
2747 fms_id = register_static_field_fms(module_name, field_name, axes%handles, &
2748 long_name=long_name, units=units, missing_value=mom_missing_value, &
2749 range=range, mask_variant=mask_variant, standard_name=standard_name, &
2750 do_not_log=do_not_log, &
2751 interp_method=interp_method, tile_count=tile_count, area=area)
2754 if (fms_id /= diag_field_not_found)
then
2757 call assert(
associated(diag),
'register_static_field: diag allocation failed')
2758 diag%fms_diag_id = fms_id
2759 diag%debug_str = trim(module_name)//
"-"//trim(field_name)
2760 if (
present(conversion)) diag%conversion_factor = conversion
2762 if (diag_cs%diag_as_chksum)
then
2765 if (
present(x_cell_method))
then
2766 call get_diag_axis_name(axes%handles(1), axis_name)
2767 call diag_field_add_attribute(fms_id,
'cell_methods', &
2768 trim(axis_name)//
':'//trim(x_cell_method))
2770 if (
present(y_cell_method))
then
2771 call get_diag_axis_name(axes%handles(2), axis_name)
2772 call diag_field_add_attribute(fms_id,
'cell_methods', &
2773 trim(axis_name)//
':'//trim(y_cell_method))
2775 if (
present(area_cell_method))
then
2776 call diag_field_add_attribute(fms_id,
'cell_methods', &
2777 'area:'//trim(area_cell_method))
2782 if (
present(cmor_field_name) .and. .not. diag_cs%diag_as_chksum)
then
2784 posted_cmor_units =
"not provided"
2785 posted_cmor_standard_name =
"not provided"
2786 posted_cmor_long_name =
"not provided"
2790 if (
present(units)) posted_cmor_units = units
2791 if (
present(standard_name)) posted_cmor_standard_name = standard_name
2792 if (
present(long_name)) posted_cmor_long_name = long_name
2795 if (
present(cmor_units)) posted_cmor_units = cmor_units
2796 if (
present(cmor_standard_name)) posted_cmor_standard_name = cmor_standard_name
2797 if (
present(cmor_long_name)) posted_cmor_long_name = cmor_long_name
2799 fms_id = register_static_field_fms(module_name, cmor_field_name, &
2800 axes%handles, long_name=trim(posted_cmor_long_name), units=trim(posted_cmor_units), &
2801 missing_value=mom_missing_value, range=range, mask_variant=mask_variant, &
2802 standard_name=trim(posted_cmor_standard_name), do_not_log=do_not_log, &
2803 interp_method=interp_method, tile_count=tile_count, area=area)
2804 if (fms_id /= diag_field_not_found)
then
2805 if (dm_id == -1)
then
2809 cmor_diag%fms_diag_id = fms_id
2810 cmor_diag%debug_str = trim(module_name)//
"-"//trim(cmor_field_name)
2811 if (
present(conversion)) cmor_diag%conversion_factor = conversion
2812 if (
present(x_cell_method))
then
2813 call get_diag_axis_name(axes%handles(1), axis_name)
2814 call diag_field_add_attribute(fms_id,
'cell_methods', trim(axis_name)//
':'//trim(x_cell_method))
2816 if (
present(y_cell_method))
then
2817 call get_diag_axis_name(axes%handles(2), axis_name)
2818 call diag_field_add_attribute(fms_id,
'cell_methods', trim(axis_name)//
':'//trim(y_cell_method))
2820 if (
present(area_cell_method))
then
2821 call diag_field_add_attribute(fms_id,
'cell_methods',
'area:'//trim(area_cell_method))
2827 if (
is_root_pe() .and. diag_cs%available_diag_doc_unit > 0)
then
2828 call log_available_diag(
associated(diag), module_name, field_name,
'',
'', diag_cs, &
2829 long_name, units, standard_name)
2830 if (
present(cmor_field_name))
then
2832 '',
'', diag_cs, posted_cmor_long_name, posted_cmor_units, &
2833 posted_cmor_standard_name)
2843 character(len=*),
intent(in) :: opt_name
2844 character(len=*),
intent(in) ::
value
2847 character(len=240) :: mesg
2850 len_ind = len_trim(
value)
2852 mesg =
" ! "//trim(opt_name)//
": "//trim(
value)
2853 write(diag_cs%available_diag_doc_unit,
'(a)') trim(mesg)
2861 type(
vardesc),
intent(in) :: var_desc
2863 type(
diag_ctrl),
intent(in),
target :: diag_cs
2864 type(time_type),
intent(in) :: day
2866 character(len=64) :: var_name
2867 character(len=48) :: units
2868 character(len=240) :: longname
2869 character(len=8) :: hor_grid, z_grid
2870 type(
axes_grp),
pointer :: axes => null()
2872 call query_vardesc(var_desc, units=units, longname=longname, hor_grid=hor_grid, &
2873 z_grid=z_grid, caller=
"ocean_register_diag")
2877 select case (z_grid)
2880 select case (hor_grid)
2882 axes => diag_cs%axesBL
2884 axes => diag_cs%axesTL
2886 axes => diag_cs%axesCuL
2888 axes => diag_cs%axesCvL
2890 axes => diag_cs%axesBL
2892 axes => diag_cs%axesTL
2894 axes => diag_cs%axesCuL
2896 axes => diag_cs%axesCvL
2898 axes => diag_cs%axeszL
2900 call mom_error(fatal,
"ocean_register_diag: " // &
2901 "unknown hor_grid component "//trim(hor_grid))
2905 select case (hor_grid)
2907 axes => diag_cs%axesBi
2909 axes => diag_cs%axesTi
2911 axes => diag_cs%axesCui
2913 axes => diag_cs%axesCvi
2915 axes => diag_cs%axesBi
2917 axes => diag_cs%axesTi
2919 axes => diag_cs%axesCui
2921 axes => diag_cs%axesCvi
2923 axes => diag_cs%axeszi
2925 call mom_error(fatal,
"ocean_register_diag: " // &
2926 "unknown hor_grid component "//trim(hor_grid))
2930 select case (hor_grid)
2932 axes => diag_cs%axesB1
2934 axes => diag_cs%axesT1
2936 axes => diag_cs%axesCu1
2938 axes => diag_cs%axesCv1
2940 axes => diag_cs%axesB1
2942 axes => diag_cs%axesT1
2944 axes => diag_cs%axesCu1
2946 axes => diag_cs%axesCv1
2948 call mom_error(fatal,
"ocean_register_diag: " // &
2949 "unknown hor_grid component "//trim(hor_grid))
2954 "ocean_register_diag: unknown z_grid component "//trim(z_grid))
2958 axes, day, trim(longname), trim(units), missing_value=-1.0e+34)
2964 character(len=*),
optional,
intent(out) :: err_msg
2966 call diag_manager_init(err_msg=err_msg)
2975 integer,
intent(in) :: nz
2977 type(
diag_ctrl),
intent(inout) :: diag_cs
2979 character(len=*),
optional,
intent(in) :: doc_file_dir
2987 integer :: ios, i, new_unit
2988 logical :: opened, new_file
2989 character(len=8) :: this_pe
2990 character(len=240) :: doc_file, doc_file_dflt, doc_path
2991 character(len=240),
allocatable :: diag_coords(:)
2993 # include "version_variable.h"
2994 character(len=40) :: mdl =
"MOM_diag_mediator"
2995 character(len=32) :: filename_appendix =
''
3002 allocate(diag_cs%diags(diag_alloc_chunk_size))
3003 diag_cs%next_free_diag_id = 1
3004 do i=1, diag_alloc_chunk_size
3011 call get_param(param_file, mdl,
'NUM_DIAG_COORDS', diag_cs%num_diag_coords, &
3012 'The number of diagnostic vertical coordinates to use. '//&
3013 'For each coordinate, an entry in DIAG_COORDS must be provided.', &
3015 if (diag_cs%num_diag_coords>0)
then
3016 allocate(diag_coords(diag_cs%num_diag_coords))
3017 if (diag_cs%num_diag_coords==1)
then
3018 call get_param(param_file, mdl,
'DIAG_COORDS', diag_coords, &
3019 'A list of string tuples associating diag_table modules to '//&
3020 'a coordinate definition used for diagnostics. Each string '//&
3021 'is of the form "MODULE_SUFFIX PARAMETER_SUFFIX COORDINATE_NAME".', &
3022 default=
'z Z ZSTAR')
3024 call get_param(param_file, mdl,
'DIAG_COORDS', diag_coords, &
3025 'A list of string tuples associating diag_table modules to '//&
3026 'a coordinate definition used for diagnostics. Each string '//&
3027 'is of the form "MODULE_SUFFIX,PARAMETER_SUFFIX,COORDINATE_NAME".', &
3028 fail_if_missing=.true.)
3030 allocate(diag_cs%diag_remap_cs(diag_cs%num_diag_coords))
3032 do i=1, diag_cs%num_diag_coords
3033 call diag_remap_init(diag_cs%diag_remap_cs(i), diag_coords(i))
3035 deallocate(diag_coords)
3038 call get_param(param_file, mdl,
'DIAG_MISVAL', diag_cs%missing_value, &
3039 'Set the default missing value to use for diagnostics.', &
3041 call get_param(param_file, mdl,
'DIAG_AS_CHKSUM', diag_cs%diag_as_chksum, &
3042 'Instead of writing diagnostics to the diag manager, write '//&
3043 'a text file containing the checksum (bitcount) of the array.', &
3046 if (diag_cs%diag_as_chksum) &
3047 diag_cs%num_chksum_diags = 0
3056 diag_cs%eqn_of_state => null()
3058 #if defined(DEBUG) || defined(__DO_SAFETY_CHECKS__)
3059 allocate(diag_cs%h_old(g%isd:g%ied,g%jsd:g%jed,nz))
3060 diag_cs%h_old(:,:,:) = 0.0
3063 diag_cs%is = g%isc - (g%isd-1) ; diag_cs%ie = g%iec - (g%isd-1)
3064 diag_cs%js = g%jsc - (g%jsd-1) ; diag_cs%je = g%jec - (g%jsd-1)
3065 diag_cs%isd = g%isd ; diag_cs%ied = g%ied
3066 diag_cs%jsd = g%jsd ; diag_cs%jed = g%jed
3069 diag_cs%dsamp(2)%isc = g%HId2%isc - (g%HId2%isd-1) ; diag_cs%dsamp(2)%iec = g%HId2%iec - (g%HId2%isd-1)
3070 diag_cs%dsamp(2)%jsc = g%HId2%jsc - (g%HId2%jsd-1) ; diag_cs%dsamp(2)%jec = g%HId2%jec - (g%HId2%jsd-1)
3071 diag_cs%dsamp(2)%isd = g%HId2%isd ; diag_cs%dsamp(2)%ied = g%HId2%ied
3072 diag_cs%dsamp(2)%jsd = g%HId2%jsd ; diag_cs%dsamp(2)%jed = g%HId2%jed
3073 diag_cs%dsamp(2)%isg = g%HId2%isg ; diag_cs%dsamp(2)%ieg = g%HId2%ieg
3074 diag_cs%dsamp(2)%jsg = g%HId2%jsg ; diag_cs%dsamp(2)%jeg = g%HId2%jeg
3075 diag_cs%dsamp(2)%isgB = g%HId2%isgB ; diag_cs%dsamp(2)%iegB = g%HId2%iegB
3076 diag_cs%dsamp(2)%jsgB = g%HId2%jsgB ; diag_cs%dsamp(2)%jegB = g%HId2%jegB
3079 if (
is_root_pe() .and. (diag_cs%available_diag_doc_unit < 0))
then
3080 write(this_pe,
'(i6.6)') pe_here()
3081 doc_file_dflt =
"available_diags."//this_pe
3082 call get_param(param_file, mdl,
"AVAILABLE_DIAGS_FILE", doc_file, &
3083 "A file into which to write a list of all available "//&
3084 "ocean diagnostics that can be included in a diag_table.", &
3085 default=doc_file_dflt, do_not_log=(diag_cs%available_diag_doc_unit/=-1))
3086 if (len_trim(doc_file) > 0)
then
3087 new_file = .true. ;
if (diag_cs%available_diag_doc_unit /= -1) new_file = .false.
3089 do new_unit=512,42,-1
3090 inquire( new_unit, opened=opened)
3091 if (.not.opened)
exit
3094 "diag_mediator_init failed to find an unused unit number.")
3097 if (
present(doc_file_dir))
then ;
if (len_trim(doc_file_dir) > 0)
then
3098 doc_path = trim(slasher(doc_file_dir))//trim(doc_file)
3101 diag_cs%available_diag_doc_unit = new_unit
3104 open(diag_cs%available_diag_doc_unit, file=trim(doc_path), access=
'SEQUENTIAL', form=
'FORMATTED', &
3105 action=
'WRITE', status=
'REPLACE', iostat=ios)
3107 open(diag_cs%available_diag_doc_unit, file=trim(doc_path), access=
'SEQUENTIAL', form=
'FORMATTED', &
3108 action=
'WRITE', status=
'OLD', position=
'APPEND', iostat=ios)
3110 inquire(diag_cs%available_diag_doc_unit, opened=opened)
3111 if ((.not.opened) .or. (ios /= 0))
then
3112 call mom_error(fatal,
"Failed to open available diags file "//trim(doc_path)//
".")
3117 if (
is_root_pe() .and. (diag_cs%chksum_iounit < 0) .and. diag_cs%diag_as_chksum)
then
3120 doc_file_dflt =
"chksum_diag"
3121 call get_param(param_file, mdl,
"CHKSUM_DIAG_FILE", doc_file, &
3122 "A file into which to write all checksums of the "//&
3123 "diagnostics listed in the diag_table.", &
3124 default=doc_file_dflt, do_not_log=(diag_cs%chksum_iounit/=-1))
3126 call get_filename_appendix(filename_appendix)
3127 if (len_trim(filename_appendix) > 0)
then
3128 doc_file = trim(doc_file) //
'.'//trim(filename_appendix)
3131 doc_file = trim(doc_file)//
"."//trim(adjustl(statslabel))
3134 if (len_trim(doc_file) > 0)
then
3135 new_file = .true. ;
if (diag_cs%chksum_iounit /= -1) new_file = .false.
3137 do new_unit=512,42,-1
3138 inquire( new_unit, opened=opened)
3139 if (.not.opened)
exit
3142 "diag_mediator_init failed to find an unused unit number.")
3145 if (
present(doc_file_dir))
then ;
if (len_trim(doc_file_dir) > 0)
then
3146 doc_path = trim(slasher(doc_file_dir))//trim(doc_file)
3149 diag_cs%chksum_iounit = new_unit
3152 open(diag_cs%chksum_iounit, file=trim(doc_path), access=
'SEQUENTIAL', form=
'FORMATTED', &
3153 action=
'WRITE', status=
'REPLACE', iostat=ios)
3155 open(diag_cs%chksum_iounit, file=trim(doc_path), access=
'SEQUENTIAL', form=
'FORMATTED', &
3156 action=
'WRITE', status=
'OLD', position=
'APPEND', iostat=ios)
3158 inquire(diag_cs%chksum_iounit, opened=opened)
3159 if ((.not.opened) .or. (ios /= 0))
then
3160 call mom_error(fatal,
"Failed to open checksum diags file "//trim(doc_path)//
".")
3169 real,
dimension(:,:,:),
target,
intent(in ) :: h
3170 real,
dimension(:,:,:),
target,
intent(in ) :: t
3171 real,
dimension(:,:,:),
target,
intent(in ) :: s
3172 type(
eos_type),
target,
intent(in ) :: eqn_of_state
3173 type(
diag_ctrl),
intent(inout) :: diag_cs
3179 diag_cs%eqn_of_state => eqn_of_state
3188 real,
target,
optional,
intent(in ) :: alt_h(:,:,:)
3190 real,
target,
optional,
intent(in ) :: alt_t(:,:,:)
3192 real,
target,
optional,
intent(in ) :: alt_s(:,:,:)
3196 real,
dimension(:,:,:),
pointer :: h_diag => null()
3197 real,
dimension(:,:,:),
pointer :: t_diag => null(), s_diag => null()
3199 if (
present(alt_h))
then
3205 if (
present(alt_t))
then
3211 if (
present(alt_s))
then
3219 if (diag_cs%diag_grid_overridden)
then
3220 call mom_error(fatal,
"diag_update_remap_grids was called, but current grids in "// &
3221 "diagnostic structure have been overridden")
3224 do i=1, diag_cs%num_diag_coords
3225 call diag_remap_update(diag_cs%diag_remap_cs(i), &
3226 diag_cs%G, diag_cs%GV, diag_cs%US, h_diag, t_diag, s_diag, &
3227 diag_cs%eqn_of_state)
3230 #if defined(DEBUG) || defined(__DO_SAFETY_CHECKS__)
3233 diag_cs%h_old(:,:,:) = diag_cs%h(:,:,:)
3243 integer,
intent(in) :: nz
3250 diag_cs%mask2dT => g%mask2dT
3251 diag_cs%mask2dBu => g%mask2dBu
3252 diag_cs%mask2dCu => g%mask2dCu
3253 diag_cs%mask2dCv => g%mask2dCv
3257 allocate(diag_cs%mask3dTL(g%isd:g%ied,g%jsd:g%jed,1:nz))
3258 allocate(diag_cs%mask3dBL(g%IsdB:g%IedB,g%JsdB:g%JedB,1:nz))
3259 allocate(diag_cs%mask3dCuL(g%IsdB:g%IedB,g%jsd:g%jed,1:nz))
3260 allocate(diag_cs%mask3dCvL(g%isd:g%ied,g%JsdB:g%JedB,1:nz))
3262 diag_cs%mask3dTL(:,:,k) = diag_cs%mask2dT(:,:)
3263 diag_cs%mask3dBL(:,:,k) = diag_cs%mask2dBu(:,:)
3264 diag_cs%mask3dCuL(:,:,k) = diag_cs%mask2dCu(:,:)
3265 diag_cs%mask3dCvL(:,:,k) = diag_cs%mask2dCv(:,:)
3267 allocate(diag_cs%mask3dTi(g%isd:g%ied,g%jsd:g%jed,1:nz+1))
3268 allocate(diag_cs%mask3dBi(g%IsdB:g%IedB,g%JsdB:g%JedB,1:nz+1))
3269 allocate(diag_cs%mask3dCui(g%IsdB:g%IedB,g%jsd:g%jed,1:nz+1))
3270 allocate(diag_cs%mask3dCvi(g%isd:g%ied,g%JsdB:g%JedB,1:nz+1))
3272 diag_cs%mask3dTi(:,:,k) = diag_cs%mask2dT(:,:)
3273 diag_cs%mask3dBi(:,:,k) = diag_cs%mask2dBu(:,:)
3274 diag_cs%mask3dCui(:,:,k) = diag_cs%mask2dCu(:,:)
3275 diag_cs%mask3dCvi(:,:,k) = diag_cs%mask2dCv(:,:)
3288 if (diag_cs%available_diag_doc_unit > -1)
then
3289 close(diag_cs%available_diag_doc_unit) ; diag_cs%available_diag_doc_unit = -2
3292 do i=1, diag_cs%num_diag_coords
3293 call diag_remap_diag_registration_closed(diag_cs%diag_remap_cs(i))
3299 type(time_type),
intent(in) :: time
3300 type(
diag_ctrl),
intent(inout) :: diag_cs
3301 logical,
optional,
intent(in) :: end_diag_manager
3306 if (diag_cs%available_diag_doc_unit > -1)
then
3307 close(diag_cs%available_diag_doc_unit) ; diag_cs%available_diag_doc_unit = -3
3309 if (diag_cs%chksum_iounit > -1)
then
3310 close(diag_cs%chksum_iounit) ; diag_cs%chksum_iounit = -3
3313 deallocate(diag_cs%diags)
3315 do i=1, diag_cs%num_diag_coords
3316 call diag_remap_end(diag_cs%diag_remap_cs(i))
3320 deallocate(diag_cs%mask3dTL)
3321 deallocate(diag_cs%mask3dBL)
3322 deallocate(diag_cs%mask3dCuL)
3323 deallocate(diag_cs%mask3dCvL)
3324 deallocate(diag_cs%mask3dTi)
3325 deallocate(diag_cs%mask3dBi)
3326 deallocate(diag_cs%mask3dCui)
3327 deallocate(diag_cs%mask3dCvi)
3328 do i=2,max_dsamp_lev
3329 deallocate(diag_cs%dsamp(i)%mask2dT)
3330 deallocate(diag_cs%dsamp(i)%mask2dBu)
3331 deallocate(diag_cs%dsamp(i)%mask2dCu)
3332 deallocate(diag_cs%dsamp(i)%mask2dCv)
3333 deallocate(diag_cs%dsamp(i)%mask3dTL)
3334 deallocate(diag_cs%dsamp(i)%mask3dBL)
3335 deallocate(diag_cs%dsamp(i)%mask3dCuL)
3336 deallocate(diag_cs%dsamp(i)%mask3dCvL)
3337 deallocate(diag_cs%dsamp(i)%mask3dTi)
3338 deallocate(diag_cs%dsamp(i)%mask3dBi)
3339 deallocate(diag_cs%dsamp(i)%mask3dCui)
3340 deallocate(diag_cs%dsamp(i)%mask3dCvi)
3343 #if defined(DEBUG) || defined(__DO_SAFETY_CHECKS__)
3344 deallocate(diag_cs%h_old)
3347 if (
present(end_diag_manager))
then
3348 if (end_diag_manager)
call diag_manager_end(time)
3354 function i2s(a,n_in)
3357 integer,
dimension(:),
intent(in) :: a
3358 integer,
optional ,
intent(in) :: n_in
3359 character(len=15) ::
i2s
3361 character(len=15) :: i2s_temp
3365 if (
present(n_in)) n = n_in
3369 write (i2s_temp,
'(I4.4)') a(i)
3370 i2s = trim(
i2s) //
'_'// trim(i2s_temp)
3379 type(
diag_type),
dimension(:),
allocatable :: tmp
3382 if (diag_cs%next_free_diag_id >
size(diag_cs%diags))
then
3383 call assert(diag_cs%next_free_diag_id -
size(diag_cs%diags) == 1, &
3384 'get_new_diag_id: inconsistent diag id')
3388 allocate(tmp(
size(diag_cs%diags)))
3389 tmp(:) = diag_cs%diags(:)
3390 deallocate(diag_cs%diags)
3391 allocate(diag_cs%diags(
size(tmp) + diag_alloc_chunk_size))
3392 diag_cs%diags(1:
size(tmp)) = tmp(:)
3396 do i=diag_cs%next_free_diag_id,
size(diag_cs%diags)
3402 diag_cs%next_free_diag_id = diag_cs%next_free_diag_id + 1
3410 diag%in_use = .false.
3411 diag%fms_diag_id = -1
3414 diag%conversion_factor = 0.
3421 integer,
intent(in ) :: diag_id
3422 type(
diag_ctrl),
target,
intent(inout) :: diag_cs
3425 type(
diag_type),
pointer :: tmp => null()
3427 if (.not. diag_cs%diags(diag_id)%in_use)
then
3428 diag => diag_cs%diags(diag_id)
3431 tmp => diag_cs%diags(diag_id)%next
3432 diag_cs%diags(diag_id)%next => diag
3435 diag%in_use = .true.
3440 subroutine log_available_diag(used, module_name, field_name, cell_methods_string, comment, &
3441 diag_CS, long_name, units, standard_name)
3442 logical,
intent(in) :: used
3443 character(len=*),
intent(in) :: module_name
3444 character(len=*),
intent(in) :: field_name
3445 character(len=*),
intent(in) :: cell_methods_string
3446 character(len=*),
intent(in) :: comment
3448 character(len=*),
optional,
intent(in) :: long_name
3449 character(len=*),
optional,
intent(in) :: units
3450 character(len=*),
optional,
intent(in) :: standard_name
3452 character(len=240) :: mesg
3455 mesg =
'"'//trim(module_name)//
'", "'//trim(field_name)//
'" [Used]'
3457 mesg =
'"'//trim(module_name)//
'", "'//trim(field_name)//
'" [Unused]'
3459 if (len(trim((comment)))>0)
then
3460 write(diag_cs%available_diag_doc_unit,
'(a,x,"(",a,")")') trim(mesg),trim(comment)
3462 write(diag_cs%available_diag_doc_unit,
'(a)') trim(mesg)
3464 if (
present(long_name))
call describe_option(
"long_name", long_name, diag_cs)
3466 if (
present(standard_name)) &
3468 if (len(trim((cell_methods_string)))>0) &
3469 call describe_option(
"cell_methods", trim(cell_methods_string), diag_cs)
3475 integer,
intent(in) :: docunit
3476 character(len=*),
intent(in) :: description
3477 integer,
intent(in) :: chksum
3479 write(docunit,
'(a,x,i9.8)') description,
chksum
3492 grid_storage%num_diag_coords = diag%num_diag_coords
3495 if (grid_storage%num_diag_coords < 1)
return
3498 allocate(grid_storage%h_state(g%isd:g%ied,g%jsd:g%jed, g%ke))
3500 allocate(grid_storage%diag_grids(diag%num_diag_coords))
3502 do m = 1, diag%num_diag_coords
3503 nz = diag%diag_remap_cs(m)%nz
3504 allocate(grid_storage%diag_grids(m)%h(g%isd:g%ied,g%jsd:g%jed, nz))
3512 real,
dimension(:,:,:),
intent(in) :: h_state
3518 if (grid_storage%num_diag_coords < 1)
return
3520 grid_storage%h_state(:,:,:) = h_state(:,:,:)
3521 do m = 1,grid_storage%num_diag_coords
3522 if (diag%diag_remap_cs(m)%nz > 0) &
3523 grid_storage%diag_grids(m)%h(:,:,:) = diag%diag_remap_cs(m)%h(:,:,:)
3536 if (grid_storage%num_diag_coords < 1)
return
3538 diag%diag_grid_overridden = .true.
3539 do m = 1,grid_storage%num_diag_coords
3540 if (diag%diag_remap_cs(m)%nz > 0) &
3541 diag%diag_remap_cs(m)%h(:,:,:) = grid_storage%diag_grids(m)%h(:,:,:)
3553 if (diag%num_diag_coords < 1)
return
3555 do m = 1,diag%num_diag_coords
3556 if (diag%diag_remap_cs(m)%nz > 0) &
3557 diag%diag_grid_temp%diag_grids(m)%h(:,:,:) = diag%diag_remap_cs(m)%h(:,:,:)
3569 if (diag%num_diag_coords < 1)
return
3571 diag%diag_grid_overridden = .false.
3572 do m = 1,diag%num_diag_coords
3573 if (diag%diag_remap_cs(m)%nz > 0) &
3574 diag%diag_remap_cs(m)%h(:,:,:) = diag%diag_grid_temp%diag_grids(m)%h(:,:,:)
3586 if (grid_storage%num_diag_coords < 1)
return
3589 deallocate(grid_storage%h_state)
3591 do m = 1, grid_storage%num_diag_coords
3592 deallocate(grid_storage%diag_grids(m)%h)
3595 deallocate(grid_storage%diag_grids)
3602 integer,
intent(in) :: nz
3606 integer :: i,j,k,ii,jj,dl
3622 do dl=2,max_dsamp_lev
3624 call downsample_mask(g%mask2dT, diag_cs%dsamp(dl)%mask2dT, dl,g%isc, g%jsc, &
3625 g%HId2%isc, g%HId2%iec, g%HId2%jsc, g%HId2%jec, g%HId2%isd, g%HId2%ied, g%HId2%jsd, g%HId2%jed)
3626 call downsample_mask(g%mask2dBu,diag_cs%dsamp(dl)%mask2dBu, dl,g%IscB,g%JscB, &
3627 g%HId2%IscB,g%HId2%IecB,g%HId2%JscB,g%HId2%JecB,g%HId2%IsdB,g%HId2%IedB,g%HId2%JsdB,g%HId2%JedB)
3628 call downsample_mask(g%mask2dCu,diag_cs%dsamp(dl)%mask2dCu, dl,g%IscB,g%JscB, &
3629 g%HId2%IscB,g%HId2%IecB,g%HId2%jsc, g%HId2%jec,g%HId2%IsdB,g%HId2%IedB,g%HId2%jsd, g%HId2%jed)
3630 call downsample_mask(g%mask2dCv,diag_cs%dsamp(dl)%mask2dCv, dl,g%isc ,g%JscB, &
3631 g%HId2%isc ,g%HId2%iec, g%HId2%JscB,g%HId2%JecB,g%HId2%isd ,g%HId2%ied, g%HId2%JsdB,g%HId2%JedB)
3634 allocate(diag_cs%dsamp(dl)%mask3dTL(g%HId2%isd:g%HId2%ied,g%HId2%jsd:g%HId2%jed,1:nz))
3635 allocate(diag_cs%dsamp(dl)%mask3dBL(g%HId2%IsdB:g%HId2%IedB,g%HId2%JsdB:g%HId2%JedB,1:nz))
3636 allocate(diag_cs%dsamp(dl)%mask3dCuL(g%HId2%IsdB:g%HId2%IedB,g%HId2%jsd:g%HId2%jed,1:nz))
3637 allocate(diag_cs%dsamp(dl)%mask3dCvL(g%HId2%isd:g%HId2%ied,g%HId2%JsdB:g%HId2%JedB,1:nz))
3639 diag_cs%dsamp(dl)%mask3dTL(:,:,k) = diag_cs%dsamp(dl)%mask2dT(:,:)
3640 diag_cs%dsamp(dl)%mask3dBL(:,:,k) = diag_cs%dsamp(dl)%mask2dBu(:,:)
3641 diag_cs%dsamp(dl)%mask3dCuL(:,:,k) = diag_cs%dsamp(dl)%mask2dCu(:,:)
3642 diag_cs%dsamp(dl)%mask3dCvL(:,:,k) = diag_cs%dsamp(dl)%mask2dCv(:,:)
3644 allocate(diag_cs%dsamp(dl)%mask3dTi(g%HId2%isd:g%HId2%ied,g%HId2%jsd:g%HId2%jed,1:nz+1))
3645 allocate(diag_cs%dsamp(dl)%mask3dBi(g%HId2%IsdB:g%HId2%IedB,g%HId2%JsdB:g%HId2%JedB,1:nz+1))
3646 allocate(diag_cs%dsamp(dl)%mask3dCui(g%HId2%IsdB:g%HId2%IedB,g%HId2%jsd:g%HId2%jed,1:nz+1))
3647 allocate(diag_cs%dsamp(dl)%mask3dCvi(g%HId2%isd:g%HId2%ied,g%HId2%JsdB:g%HId2%JedB,1:nz+1))
3649 diag_cs%dsamp(dl)%mask3dTi(:,:,k) = diag_cs%dsamp(dl)%mask2dT(:,:)
3650 diag_cs%dsamp(dl)%mask3dBi(:,:,k) = diag_cs%dsamp(dl)%mask2dBu(:,:)
3651 diag_cs%dsamp(dl)%mask3dCui(:,:,k) = diag_cs%dsamp(dl)%mask2dCu(:,:)
3652 diag_cs%dsamp(dl)%mask3dCvi(:,:,k) = diag_cs%dsamp(dl)%mask2dCv(:,:)
3660 integer,
intent(in) :: fo1
3661 integer,
intent(in) :: fo2
3662 integer,
intent(in) :: dl
3664 integer,
intent(out) :: isv
3665 integer,
intent(out) :: iev
3666 integer,
intent(out) :: jsv
3667 integer,
intent(out) :: jev
3669 integer :: dszi,cszi,dszj,cszj,f1,f2
3670 character(len=500) :: mesg
3671 logical,
save :: first_check = .true.
3679 if(first_check)
then
3680 if(mod(diag_cs%ie-diag_cs%is+1, dl) .ne. 0 .OR. mod(diag_cs%je-diag_cs%js+1, dl) .ne. 0)
then
3681 write (mesg,*)
"Non-commensurate downsampled domain is not supported. "//&
3682 "Please choose a layout such that NIGLOBAL/Layout_X and NJGLOBAL/Layout_Y are both divisible by dl=",dl,&
3683 " Current domain extents: ", diag_cs%is,diag_cs%ie, diag_cs%js,diag_cs%je
3684 call mom_error(fatal,
"downsample_diag_indices_get: "//trim(mesg))
3686 first_check = .false.
3689 cszi = diag_cs%dsamp(dl)%iec-diag_cs%dsamp(dl)%isc +1 ; dszi = diag_cs%dsamp(dl)%ied-diag_cs%dsamp(dl)%isd +1
3690 cszj = diag_cs%dsamp(dl)%jec-diag_cs%dsamp(dl)%jsc +1 ; dszj = diag_cs%dsamp(dl)%jed-diag_cs%dsamp(dl)%jsd +1
3691 isv = diag_cs%dsamp(dl)%isc ; iev = diag_cs%dsamp(dl)%iec
3692 jsv = diag_cs%dsamp(dl)%jsc ; jev = diag_cs%dsamp(dl)%jec
3696 if (diag_cs%G%symmetric)
then
3697 f1 = f1 + mod(fo1,dl)
3698 f2 = f2 + mod(fo2,dl)
3700 if ( f1 == dszi )
then
3701 isv = diag_cs%dsamp(dl)%isc ; iev = diag_cs%dsamp(dl)%iec
3703 elseif ( f1 == dszi + 1 )
then
3704 isv = diag_cs%dsamp(dl)%isc ; iev = diag_cs%dsamp(dl)%iec+1
3705 elseif ( f1 == cszi)
then
3706 isv = 1 ; iev = (diag_cs%dsamp(dl)%iec-diag_cs%dsamp(dl)%isc) +1
3707 elseif ( f1 == cszi + 1 )
then
3708 isv = 1 ; iev = (diag_cs%dsamp(dl)%iec-diag_cs%dsamp(dl)%isc) +2
3710 write (mesg,*)
" peculiar size ",f1,
" in i-direction\n"//&
3711 "does not match one of ", cszi, cszi+1, dszi, dszi+1
3712 call mom_error(fatal,
"downsample_diag_indices_get: "//trim(mesg))
3714 if ( f2 == dszj )
then
3715 jsv = diag_cs%dsamp(dl)%jsc ; jev = diag_cs%dsamp(dl)%jec
3716 elseif ( f2 == dszj + 1 )
then
3717 jsv = diag_cs%dsamp(dl)%jsc ; jev = diag_cs%dsamp(dl)%jec+1
3718 elseif ( f2 == cszj)
then
3719 jsv = 1 ; jev = (diag_cs%dsamp(dl)%jec-diag_cs%dsamp(dl)%jsc) +1
3720 elseif ( f2 == cszj + 1 )
then
3721 jsv = 1 ; jev = (diag_cs%dsamp(dl)%jec-diag_cs%dsamp(dl)%jsc) +2
3723 write (mesg,*)
" peculiar size ",f2,
" in j-direction\n"//&
3724 "does not match one of ", cszj, cszj+1, dszj, dszj+1
3725 call mom_error(fatal,
"downsample_diag_indices_get: "//trim(mesg))
3733 real,
dimension(:,:,:),
pointer :: locfield
3734 real,
dimension(:,:,:),
allocatable,
intent(inout) :: locfield_dsamp
3737 integer,
intent(in) :: dl
3738 integer,
intent(inout) :: isv
3739 integer,
intent(inout) :: iev
3740 integer,
intent(inout) :: jsv
3741 integer,
intent(inout) :: jev
3742 real,
optional,
target,
intent(in) :: mask(:,:,:)
3744 real,
dimension(:,:,:),
pointer :: locmask
3745 integer :: f1,f2,isv_o,jsv_o
3757 if (
present(mask))
then
3759 elseif (
associated(diag%axes%mask3d))
then
3760 locmask => diag%axes%mask3d
3762 call mom_error(fatal,
"downsample_diag_field_3d: Cannot downsample without a mask!!! ")
3765 call downsample_field(locfield, locfield_dsamp, dl, diag%xyz_method, locmask, diag_cs, diag, &
3766 isv_o,jsv_o,isv,iev,jsv,jev)
3774 real,
dimension(:,:),
pointer :: locfield
3775 real,
dimension(:,:),
allocatable,
intent(inout) :: locfield_dsamp
3778 integer,
intent(in) :: dl
3779 integer,
intent(inout) :: isv
3780 integer,
intent(inout) :: iev
3781 integer,
intent(inout) :: jsv
3782 integer,
intent(inout) :: jev
3783 real,
optional,
target,
intent(in) :: mask(:,:)
3785 real,
dimension(:,:),
pointer :: locmask
3786 integer :: f1,f2,isv_o,jsv_o
3798 if (
present(mask))
then
3800 elseif (
associated(diag%axes%mask2d))
then
3801 locmask => diag%axes%mask2d
3803 call mom_error(fatal,
"downsample_diag_field_2d: Cannot downsample without a mask!!! ")
3806 call downsample_field(locfield, locfield_dsamp, dl, diag%xyz_method, locmask, diag_cs,diag, &
3807 isv_o,jsv_o,isv,iev,jsv,jev)
3848 subroutine downsample_field_3d(field_in, field_out, dl, method, mask, diag_cs, diag,isv_o,jsv_o,isv_d,iev_d,jsv_d,jev_d)
3849 real,
dimension(:,:,:),
pointer :: field_in
3850 real,
dimension(:,:,:),
allocatable :: field_out
3851 integer,
intent(in) :: dl
3852 integer,
intent(in) :: method
3853 real,
dimension(:,:,:),
pointer :: mask
3856 integer,
intent(in) :: isv_o
3857 integer,
intent(in) :: jsv_o
3858 integer,
intent(in) :: isv_d
3859 integer,
intent(in) :: iev_d
3860 integer,
intent(in) :: jsv_d
3861 integer,
intent(in) :: jev_d
3863 character(len=240) :: mesg
3864 integer :: i,j,ii,jj,i0,j0,f1,f2,f_in1,f_in2
3866 real :: ave,total_weight,weight
3871 ks = 1 ; ke =
size(field_in,3)
3872 eps_face = 1.0e-20 * diag_cs%G%US%m_to_L * diag_cs%GV%m_to_H
3873 eps_area = 1.0e-20 * diag_cs%G%US%m_to_L**2
3874 eps_vol = 1.0e-20 * diag_cs%G%US%m_to_L**2 * diag_cs%GV%m_to_H
3879 f_in1 =
size(field_in,1)
3880 f_in2 =
size(field_in,2)
3884 if (diag_cs%G%symmetric)
then
3885 f1 = f1 + mod(f_in1,dl)
3886 f2 = f2 + mod(f_in2,dl)
3888 allocate(field_out(1:f1,1:f2,ks:ke))
3891 if (method ==
mmm)
then
3892 do k= ks,ke ;
do j=jsv_d,jev_d ;
do i=isv_d,iev_d
3893 i0 = isv_o+dl*(i-isv_d)
3894 j0 = jsv_o+dl*(j-jsv_d)
3897 do jj=j0,j0+dl-1 ;
do ii=i0,i0+dl-1
3899 weight = mask(ii,jj,k) * diag_cs%G%areaT(ii,jj) * diag_cs%h(ii,jj,k)
3900 total_weight = total_weight + weight
3901 ave = ave+field_in(ii,jj,k) * weight
3903 field_out(i,j,k) = ave/(total_weight + eps_vol)
3905 elseif (method ==
sss)
then
3906 do k= ks,ke ;
do j=jsv_d,jev_d ;
do i=isv_d,iev_d
3907 i0 = isv_o+dl*(i-isv_d)
3908 j0 = jsv_o+dl*(j-jsv_d)
3910 do jj=j0,j0+dl-1 ;
do ii=i0,i0+dl-1
3911 weight = mask(ii,jj,k)
3912 ave = ave+field_in(ii,jj,k)*weight
3914 field_out(i,j,k) = ave
3916 elseif(method ==
mmp .or. method ==
mms)
then
3917 do k= ks,ke ;
do j=jsv_d,jev_d ;
do i=isv_d,iev_d
3918 i0 = isv_o+dl*(i-isv_d)
3919 j0 = jsv_o+dl*(j-jsv_d)
3922 do jj=j0,j0+dl-1 ;
do ii=i0,i0+dl-1
3924 weight = mask(ii,jj,k) * diag_cs%G%areaT(ii,jj)
3925 total_weight = total_weight + weight
3926 ave = ave+field_in(ii,jj,k)*weight
3928 field_out(i,j,k) = ave / (total_weight+eps_area)
3930 elseif(method ==
pmm)
then
3931 do k= ks,ke ;
do j=jsv_d,jev_d ;
do i=isv_d,iev_d
3932 i0 = isv_o+dl*(i-isv_d)
3933 j0 = jsv_o+dl*(j-jsv_d)
3938 weight =mask(ii,jj,k) * diag_cs%G%dyCu(ii,jj) * diag_cs%h(ii,jj,k)
3939 total_weight = total_weight +weight
3940 ave=ave+field_in(ii,jj,k)*weight
3942 field_out(i,j,k) = ave/(total_weight+eps_face)
3944 elseif(method ==
pss)
then
3945 do k= ks,ke ;
do j=jsv_d,jev_d ;
do i=isv_d,iev_d
3946 i0 = isv_o+dl*(i-isv_d)
3947 j0 = jsv_o+dl*(j-jsv_d)
3951 weight =mask(ii,jj,k)
3952 ave=ave+field_in(ii,jj,k)*weight
3954 field_out(i,j,k) = ave
3956 elseif(method ==
sps)
then
3957 do k= ks,ke ;
do j=jsv_d,jev_d ;
do i=isv_d,iev_d
3958 i0 = isv_o+dl*(i-isv_d)
3959 j0 = jsv_o+dl*(j-jsv_d)
3963 weight =mask(ii,jj,k)
3964 ave=ave+field_in(ii,jj,k)*weight
3966 field_out(i,j,k) = ave
3968 elseif(method ==
mpm)
then
3969 do k= ks,ke ;
do j=jsv_d,jev_d ;
do i=isv_d,iev_d
3970 i0 = isv_o+dl*(i-isv_d)
3971 j0 = jsv_o+dl*(j-jsv_d)
3976 weight = mask(ii,jj,k) * diag_cs%G%dxCv(ii,jj) * diag_cs%h(ii,jj,k)
3977 total_weight = total_weight + weight
3978 ave=ave+field_in(ii,jj,k)*weight
3980 field_out(i,j,k) = ave/(total_weight+eps_face)
3982 elseif(method ==
msk)
then
3983 field_out(:,:,:) = 0.0
3984 do k= ks,ke ;
do j=jsv_d,jev_d ;
do i=isv_d,iev_d
3985 i0 = isv_o+dl*(i-isv_d)
3986 j0 = jsv_o+dl*(j-jsv_d)
3988 do jj=j0,j0+dl-1 ;
do ii=i0,i0+dl-1
3989 ave=ave+field_in(ii,jj,k)
3991 if(ave > 0.0) field_out(i,j,k)=1.0
3994 write (mesg,*)
" unknown sampling method: ",method
3995 call mom_error(fatal,
"downsample_field_3d: "//trim(mesg)//
" "//trim(diag%debug_str))
4004 isv_o, jsv_o, isv_d, iev_d, jsv_d, jev_d)
4005 real,
dimension(:,:),
pointer :: field_in
4006 real,
dimension(:,:),
allocatable :: field_out
4007 integer,
intent(in) :: dl
4008 integer,
intent(in) :: method
4009 real,
dimension(:,:),
pointer :: mask
4012 integer,
intent(in) :: isv_o
4013 integer,
intent(in) :: jsv_o
4014 integer,
intent(in) :: isv_d
4015 integer,
intent(in) :: iev_d
4016 integer,
intent(in) :: jsv_d
4017 integer,
intent(in) :: jev_d
4019 character(len=240) :: mesg
4020 integer :: i,j,ii,jj,i0,j0,f1,f2,f_in1,f_in2
4021 real :: ave, total_weight, weight
4022 real :: epsilon = 1.0e-20
4026 eps_len = 1.0e-20 * diag_cs%G%US%m_to_L
4027 eps_area = 1.0e-20 * diag_cs%G%US%m_to_L**2
4033 f_in1 =
size(field_in,1)
4034 f_in2 =
size(field_in,2)
4038 if (diag_cs%G%symmetric)
then
4039 f1 = f1 + mod(f_in1,dl)
4040 f2 = f2 + mod(f_in2,dl)
4042 allocate(field_out(1:f1,1:f2))
4044 if (method ==
mmp)
then
4045 do j=jsv_d,jev_d ;
do i=isv_d,iev_d
4046 i0 = isv_o+dl*(i-isv_d)
4047 j0 = jsv_o+dl*(j-jsv_d)
4050 do jj=j0,j0+dl-1 ;
do ii=i0,i0+dl-1
4052 weight = mask(ii,jj)*diag_cs%G%areaT(ii,jj)
4053 total_weight = total_weight + weight
4054 ave = ave+field_in(ii,jj)*weight
4056 field_out(i,j) = ave/(total_weight + eps_area)
4058 elseif(method ==
ssp)
then
4059 do j=jsv_d,jev_d ;
do i=isv_d,iev_d
4060 i0 = isv_o+dl*(i-isv_d)
4061 j0 = jsv_o+dl*(j-jsv_d)
4064 do jj=j0,j0+dl-1 ;
do ii=i0,i0+dl-1
4066 weight = mask(ii,jj)
4067 total_weight = total_weight + weight
4068 ave=ave+field_in(ii,jj)*weight
4070 field_out(i,j) = ave/(total_weight+epsilon)
4072 elseif(method ==
psp)
then
4073 do j=jsv_d,jev_d ;
do i=isv_d,iev_d
4074 i0 = isv_o+dl*(i-isv_d)
4075 j0 = jsv_o+dl*(j-jsv_d)
4080 weight = mask(ii,jj)
4081 total_weight = total_weight +weight
4082 ave=ave+field_in(ii,jj)*weight
4084 field_out(i,j) = ave/(total_weight+epsilon)
4086 elseif(method ==
spp)
then
4087 do j=jsv_d,jev_d ;
do i=isv_d,iev_d
4088 i0 = isv_o+dl*(i-isv_d)
4089 j0 = jsv_o+dl*(j-jsv_d)
4094 weight = mask(ii,jj)
4095 total_weight = total_weight +weight
4096 ave=ave+field_in(ii,jj)*weight
4098 field_out(i,j) = ave/(total_weight+epsilon)
4100 elseif(method ==
pmp)
then
4101 do j=jsv_d,jev_d ;
do i=isv_d,iev_d
4102 i0 = isv_o+dl*(i-isv_d)
4103 j0 = jsv_o+dl*(j-jsv_d)
4108 weight = mask(ii,jj) * diag_cs%G%dyCu(ii,jj)
4109 total_weight = total_weight +weight
4110 ave=ave+field_in(ii,jj)*weight
4112 field_out(i,j) = ave/(total_weight+eps_len)
4114 elseif(method ==
mpp)
then
4115 do j=jsv_d,jev_d ;
do i=isv_d,iev_d
4116 i0 = isv_o+dl*(i-isv_d)
4117 j0 = jsv_o+dl*(j-jsv_d)
4122 weight = mask(ii,jj)* diag_cs%G%dxCv(ii,jj)
4123 total_weight = total_weight +weight
4124 ave=ave+field_in(ii,jj)*weight
4126 field_out(i,j) = ave/(total_weight+eps_len)
4128 elseif(method ==
msk)
then
4129 field_out(:,:) = 0.0
4130 do j=jsv_d,jev_d ;
do i=isv_d,iev_d
4131 i0 = isv_o+dl*(i-isv_d)
4132 j0 = jsv_o+dl*(j-jsv_d)
4134 do jj=j0,j0+dl-1 ;
do ii=i0,i0+dl-1
4135 ave=ave+field_in(ii,jj)
4137 if(ave > 0.0) field_out(i,j)=1.0
4140 write (mesg,*)
" unknown sampling method: ",method
4141 call mom_error(fatal,
"downsample_field_2d: "//trim(mesg)//
" "//trim(diag%debug_str))
4149 subroutine downsample_mask_2d(field_in, field_out, dl, isc_o, jsc_o, isc_d, iec_d, jsc_d, jec_d, &
4150 isd_d, ied_d, jsd_d, jed_d)
4151 real,
dimension(:,:),
intent(in) :: field_in
4152 real,
dimension(:,:),
pointer :: field_out
4153 integer,
intent(in) :: dl
4154 integer,
intent(in) :: isc_o
4155 integer,
intent(in) :: jsc_o
4156 integer,
intent(in) :: isc_d
4157 integer,
intent(in) :: iec_d
4158 integer,
intent(in) :: jsc_d
4159 integer,
intent(in) :: jec_d
4160 integer,
intent(in) :: isd_d
4161 integer,
intent(in) :: ied_d
4162 integer,
intent(in) :: jsd_d
4163 integer,
intent(in) :: jed_d
4165 integer :: i,j,ii,jj,i0,j0
4166 real :: tot_non_zero
4168 allocate(field_out(isd_d:ied_d,jsd_d:jed_d))
4169 field_out(:,:) = 0.0
4170 do j=jsc_d,jec_d ;
do i=isc_d,iec_d
4171 i0 = isc_o+dl*(i-isc_d)
4172 j0 = jsc_o+dl*(j-jsc_d)
4174 do jj=j0,j0+dl-1 ;
do ii=i0,i0+dl-1
4175 tot_non_zero = tot_non_zero + field_in(ii,jj)
4177 if(tot_non_zero > 0.0) field_out(i,j)=1.0
4184 subroutine downsample_mask_3d(field_in, field_out, dl, isc_o, jsc_o, isc_d, iec_d, jsc_d, jec_d, &
4185 isd_d, ied_d, jsd_d, jed_d)
4186 real,
dimension(:,:,:),
intent(in) :: field_in
4187 real,
dimension(:,:,:),
pointer :: field_out
4188 integer,
intent(in) :: dl
4189 integer,
intent(in) :: isc_o
4190 integer,
intent(in) :: jsc_o
4191 integer,
intent(in) :: isc_d
4192 integer,
intent(in) :: iec_d
4193 integer,
intent(in) :: jsc_d
4194 integer,
intent(in) :: jec_d
4195 integer,
intent(in) :: isd_d
4196 integer,
intent(in) :: ied_d
4197 integer,
intent(in) :: jsd_d
4198 integer,
intent(in) :: jed_d
4200 integer :: i,j,ii,jj,i0,j0,k,ks,ke
4201 real :: tot_non_zero
4203 ks = lbound(field_in,3) ; ke = ubound(field_in,3)
4204 allocate(field_out(isd_d:ied_d,jsd_d:jed_d,ks:ke))
4205 field_out(:,:,:) = 0.0
4206 do k= ks,ke ;
do j=jsc_d,jec_d ;
do i=isc_d,iec_d
4207 i0 = isc_o+dl*(i-isc_d)
4208 j0 = jsc_o+dl*(j-jsc_d)
4210 do jj=j0,j0+dl-1 ;
do ii=i0,i0+dl-1
4211 tot_non_zero = tot_non_zero + field_in(ii,jj,k)
4213 if(tot_non_zero > 0.0) field_out(i,j,k)=1.0