Skip to content

Commit 1cf9562

Browse files
committed
Generalize support for downsample diagnostics
- Generalize _d2 diagnostics to arbitrary _dl - The maximum level MAX_DSAMP_LEV needs to be specified. This limitation could later be enhanced by getting the desired levels of downsampling from MOM_parameter file, e.g., DOWNSAMPLE_DIAG_LEVELS = /2,3,4/
1 parent 57feb58 commit 1cf9562

4 files changed

Lines changed: 140 additions & 146 deletions

File tree

config_src/infra/FMS2/MOM_diag_manager_infra.F90

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
!! those APIs would be applied here).
1111
module MOM_diag_manager_infra
1212

13+
#define MAX_DSAMP_LEV 3
14+
1315
use, intrinsic :: iso_fortran_env, only : real64
1416
use diag_axis_mod, only : fms_axis_init=>diag_axis_init
1517
use diag_axis_mod, only : fms_get_diag_axis_name => get_diag_axis_name
@@ -116,10 +118,10 @@ integer function MOM_diag_axis_init(name, data, units, cart_name, long_name, MOM
116118
MOM_diag_axis_init = fms_axis_init(name, data, units, cart_name, long_name=long_name, &
117119
direction=direction, set_name=set_name, edges=edges, &
118120
domain2=MOM_domain%mpp_domain, domain_position=position)
119-
elseif (coarsening == 2) then
121+
elseif (coarsening <= MAX_DSAMP_LEV) then
120122
MOM_diag_axis_init = fms_axis_init(name, data, units, cart_name, long_name=long_name, &
121123
direction=direction, set_name=set_name, edges=edges, &
122-
domain2=MOM_domain%mpp_domain_d2, domain_position=position)
124+
domain2=MOM_domain%mpp_domain_d(coarsening), domain_position=position)
123125
else
124126
call MOM_error(FATAL, "diag_axis_init called with an invalid value of coarsen.")
125127
endif

config_src/infra/FMS2/MOM_domain_infra.F90

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ module MOM_domain_infra
3434

3535
! The `group_pass_type` fields are never accessed, so we keep it as an FMS type
3636
use mpp_domains_mod, only : group_pass_type => mpp_group_update_type
37+
#define MAX_DSAMP_LEV 3
3738

3839
implicit none ; private
3940

@@ -133,7 +134,7 @@ module MOM_domain_infra
133134
character(len=64) :: name !< The name of this domain
134135
type(domain2D), pointer :: mpp_domain => NULL() !< The FMS domain with halos
135136
!! on this processor, centered at h points.
136-
type(domain2D), pointer :: mpp_domain_d2 => NULL() !< A coarse FMS domain with halos
137+
type(domain2D), pointer :: mpp_domain_d(:) => NULL() !< A coarse FMS domain with halos
137138
!! on this processor, centered at h points.
138139
integer :: niglobal !< The total horizontal i-domain size.
139140
integer :: njglobal !< The total horizontal j-domain size.
@@ -1371,14 +1372,14 @@ subroutine create_MOM_domain(MOM_dom, n_global, n_halo, reentrant, tripolar_N, l
13711372
integer, dimension(4) :: global_indices ! The lower and upper global i- and j-index bounds
13721373
integer :: X_FLAGS ! A combination of integers encoding the x-direction grid connectivity.
13731374
integer :: Y_FLAGS ! A combination of integers encoding the y-direction grid connectivity.
1374-
integer :: xhalo_d2, yhalo_d2
1375+
integer :: dl
13751376
character(len=200) :: mesg ! A string for use in error messages
13761377
logical :: mask_table_exists ! Mask_table is present and the file it points to exists
13771378

13781379
if (.not.associated(MOM_dom)) then
13791380
allocate(MOM_dom)
13801381
allocate(MOM_dom%mpp_domain)
1381-
allocate(MOM_dom%mpp_domain_d2)
1382+
do dl=2,MAX_DSAMP_LEV ; allocate(MOM_dom%mpp_domain_d(dl)) ; enddo
13821383
endif
13831384

13841385
MOM_dom%name = "MOM" ; if (present(domain_name)) MOM_dom%name = trim(domain_name)
@@ -1446,11 +1447,12 @@ subroutine create_MOM_domain(MOM_dom, n_global, n_halo, reentrant, tripolar_N, l
14461447

14471448
call clone_MD_to_d2D(MOM_dom, MOM_dom%mpp_domain)
14481449

1449-
!For downsampled domain, recommend a halo of 1 (or 0?) since we're not doing wide-stencil computations.
1450-
!But that does not work because the downsampled field would not have the correct size to pass the checks, e.g., we get
1451-
!error: downsample_diag_indices_get: peculiar size 28 in i-direction\ndoes not match one of 24 25 26 27
1452-
! call clone_MD_to_d2D(MOM_dom, MOM_dom%mpp_domain_d2, halo_size=(MOM_dom%nihalo/2), coarsen=2)
1453-
call clone_MD_to_d2D(MOM_dom, MOM_dom%mpp_domain_d2, coarsen=2)
1450+
do dl=2,MAX_DSAMP_LEV
1451+
!Downsample diagnostics calculations do not need halos.
1452+
call clone_MD_to_d2D(MOM_dom, MOM_dom%mpp_domain_d(dl), coarsen=dl, halo_size=0, &
1453+
domain_name="MOM_domain_d" // char(48+dl))
1454+
enddo
1455+
14541456
end subroutine create_MOM_domain
14551457

14561458
!> dealloc_MOM_domain deallocates memory associated with a pointer to a MOM_domain_type
@@ -1460,6 +1462,7 @@ subroutine deallocate_MOM_domain(MOM_domain, cursory)
14601462
logical, optional, intent(in) :: cursory !< If true do not deallocate fields associated
14611463
!! with the underlying infrastructure
14621464
logical :: invasive ! If true, deallocate fields associated with the underlying infrastructure
1465+
integer :: dl
14631466

14641467
invasive = .true. ; if (present(cursory)) invasive = .not.cursory
14651468

@@ -1468,9 +1471,11 @@ subroutine deallocate_MOM_domain(MOM_domain, cursory)
14681471
if (invasive) call mpp_deallocate_domain(MOM_domain%mpp_domain)
14691472
deallocate(MOM_domain%mpp_domain)
14701473
endif
1471-
if (associated(MOM_domain%mpp_domain_d2)) then
1472-
if (invasive) call mpp_deallocate_domain(MOM_domain%mpp_domain_d2)
1473-
deallocate(MOM_domain%mpp_domain_d2)
1474+
if (associated(MOM_domain%mpp_domain_d)) then
1475+
if (invasive) then
1476+
do dl=2,MAX_DSAMP_LEV ; call mpp_deallocate_domain(MOM_domain%mpp_domain_d(dl)); enddo
1477+
endif
1478+
deallocate(MOM_domain%mpp_domain_d)
14741479
endif
14751480
if (associated(MOM_domain%maskmap)) deallocate(MOM_domain%maskmap)
14761481
deallocate(MOM_domain)
@@ -1567,7 +1572,7 @@ subroutine clone_MD_to_MD(MD_in, MOM_dom, min_halo, halo_size, symmetric, domain
15671572
integer, dimension(:), allocatable :: exnj ! The extents of the grid for each j-row of the layout.
15681573
! The sum of exni must equal MOM_dom%niglobal.
15691574
integer :: qturns ! The number of quarter turns, restricted to the range of 0 to 3.
1570-
integer :: i, j, nl1, nl2
1575+
integer :: i, j, nl1, nl2, dl
15711576
integer :: io_layout_in(2)
15721577

15731578
qturns = 0
@@ -1582,7 +1587,7 @@ subroutine clone_MD_to_MD(MD_in, MOM_dom, min_halo, halo_size, symmetric, domain
15821587
if (.not.associated(MOM_dom)) then
15831588
allocate(MOM_dom)
15841589
allocate(MOM_dom%mpp_domain)
1585-
allocate(MOM_dom%mpp_domain_d2)
1590+
do dl=2,MAX_DSAMP_LEV ; allocate(MOM_dom%mpp_domain_d(dl)) ; enddo
15861591
endif
15871592

15881593
! Save the extra data for creating other domains of different resolution that overlay this domain
@@ -1704,7 +1709,11 @@ subroutine clone_MD_to_MD(MD_in, MOM_dom, min_halo, halo_size, symmetric, domain
17041709
endif
17051710

17061711
call clone_MD_to_d2D(MOM_dom, MOM_dom%mpp_domain, xextent=exni, yextent=exnj)
1707-
call clone_MD_to_d2D(MOM_dom, MOM_dom%mpp_domain_d2, domain_name=MOM_dom%name, coarsen=2)
1712+
do dl=2,MAX_DSAMP_LEV
1713+
!Downsample diagnostics calculations do not need halos.
1714+
call clone_MD_to_d2D(MOM_dom, MOM_dom%mpp_domain_d(dl), coarsen=dl, halo_size=0, &
1715+
domain_name="MOM_domain_d" // char(48+dl))
1716+
enddo
17081717

17091718
end subroutine clone_MD_to_MD
17101719

@@ -1842,12 +1851,12 @@ subroutine get_domain_extent_MD(Domain, isc, iec, jsc, jec, isd, ied, jsd, jed,
18421851
call mpp_get_compute_domain(Domain%mpp_domain, isc, iec, jsc, jec)
18431852
call mpp_get_data_domain(Domain%mpp_domain, isd, ied, jsd, jed)
18441853
call mpp_get_global_domain(Domain%mpp_domain, isg_, ieg_, jsg_, jeg_)
1845-
elseif (coarsen_lev == 2) then
1846-
if (.not.associated(Domain%mpp_domain_d2)) call MOM_error(FATAL, &
1847-
"get_domain_extent called with coarsen=2, but Domain%mpp_domain_d2 is not associated.")
1848-
call mpp_get_compute_domain(Domain%mpp_domain_d2, isc, iec, jsc, jec)
1849-
call mpp_get_data_domain(Domain%mpp_domain_d2, isd, ied, jsd, jed)
1850-
call mpp_get_global_domain(Domain%mpp_domain_d2, isg_, ieg_, jsg_, jeg_)
1854+
elseif (coarsen_lev <= MAX_DSAMP_LEV) then
1855+
if (.not.associated(Domain%mpp_domain_d)) call MOM_error(FATAL, &
1856+
"get_domain_extent called with coarsen_lev, but Domain%mpp_domain_d(coarsen_lev) is not associated.")
1857+
call mpp_get_compute_domain(Domain%mpp_domain_d(coarsen_lev), isc, iec, jsc, jec)
1858+
call mpp_get_data_domain(Domain%mpp_domain_d(coarsen_lev), isd, ied, jsd, jed)
1859+
call mpp_get_global_domain(Domain%mpp_domain_d(coarsen_lev), isg_, ieg_, jsg_, jeg_)
18511860
else
18521861
call MOM_error(FATAL, "get_domain_extent called with an unsupported level of coarsening.")
18531862
endif

src/core/MOM_grid.F90

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ module MOM_grid
1515
implicit none ; private
1616

1717
#include <MOM_memory.h>
18+
#define MAX_DSAMP_LEV 3
1819

1920
public MOM_grid_init, MOM_grid_end, set_derived_metrics, set_first_direction
2021
public isPointInCell, hor_index_type, get_global_grid_size
@@ -29,7 +30,7 @@ module MOM_grid
2930
type(MOM_domain_type), pointer :: Domain => NULL() !< Ocean model domain
3031
type(MOM_domain_type), pointer :: Domain_aux => NULL() !< A non-symmetric auxiliary domain type.
3132
type(hor_index_type) :: HI !< Horizontal index ranges
32-
type(hor_index_type) :: HId2 !< Horizontal index ranges for level-2-downsampling
33+
type(hor_index_type) :: HId(2:MAX_DSAMP_LEV) !< Horizontal index ranges for downsampling, level 2 to MAX_DSAMP_LEV.
3334

3435
integer :: isc !< The start i-index of cell centers within the computational domain
3536
integer :: iec !< The end i-index of cell centers within the computational domain
@@ -237,7 +238,7 @@ subroutine MOM_grid_init(G, param_file, US, HI, global_indexing, bathymetry_at_v
237238
integer :: isd, ied, jsd, jed
238239
integer :: IsdB, IedB, JsdB, JedB
239240
integer :: ied_max, jed_max
240-
integer :: niblock, njblock, nihalo, njhalo, nblocks, n, i, j
241+
integer :: niblock, njblock, nihalo, njhalo, nblocks, n, i, j, dl
241242
logical :: local_indexing ! If false use global index values instead of having
242243
! the data domain on each processor start at 1.
243244
! This include declares and sets the variable "version".
@@ -402,22 +403,25 @@ subroutine MOM_grid_init(G, param_file, US, HI, global_indexing, bathymetry_at_v
402403
if ( G%block(nblocks)%jed+G%block(nblocks)%jdg_offset > G%HI%jed + G%HI%jdg_offset ) &
403404
call MOM_error(FATAL, "MOM_grid_init: G%jed_bk > G%jed")
404405

405-
call get_domain_extent(G%Domain, G%HId2%isc, G%HId2%iec, G%HId2%jsc, G%HId2%jec, &
406-
G%HId2%isd, G%HId2%ied, G%HId2%jsd, G%HId2%jed, &
407-
G%HId2%isg, G%HId2%ieg, G%HId2%jsg, G%HId2%jeg, coarsen=2)
406+
! Initialize the global grid extents for all levels of diagnosics coarsening.
407+
do dl=2,MAX_DSAMP_LEV
408+
call get_domain_extent(G%Domain, G%HId(dl)%isc, G%HId(dl)%iec, G%HId(dl)%jsc, G%HId(dl)%jec, &
409+
G%HId(dl)%isd, G%HId(dl)%ied, G%HId(dl)%jsd, G%HId(dl)%jed, &
410+
G%HId(dl)%isg, G%HId(dl)%ieg, G%HId(dl)%jsg, G%HId(dl)%jeg, coarsen=dl)
408411

409-
! Set array sizes for fields that are discretized at tracer cell boundaries.
410-
G%HId2%IscB = G%HId2%isc ; G%HId2%JscB = G%HId2%jsc
411-
G%HId2%IsdB = G%HId2%isd ; G%HId2%JsdB = G%HId2%jsd
412-
G%HId2%IsgB = G%HId2%isg ; G%HId2%JsgB = G%HId2%jsg
413-
if (G%symmetric) then
414-
G%HId2%IscB = G%HId2%isc-1 ; G%HId2%JscB = G%HId2%jsc-1
415-
G%HId2%IsdB = G%HId2%isd-1 ; G%HId2%JsdB = G%HId2%jsd-1
416-
G%HId2%IsgB = G%HId2%isg-1 ; G%HId2%JsgB = G%HId2%jsg-1
417-
endif
418-
G%HId2%IecB = G%HId2%iec ; G%HId2%JecB = G%HId2%jec
419-
G%HId2%IedB = G%HId2%ied ; G%HId2%JedB = G%HId2%jed
420-
G%HId2%IegB = G%HId2%ieg ; G%HId2%JegB = G%HId2%jeg
412+
! Set array sizes for fields that are discretized at tracer cell boundaries.
413+
G%HId(dl)%IscB = G%HId(dl)%isc ; G%HId(dl)%JscB = G%HId(dl)%jsc
414+
G%HId(dl)%IsdB = G%HId(dl)%isd ; G%HId(dl)%JsdB = G%HId(dl)%jsd
415+
G%HId(dl)%IsgB = G%HId(dl)%isg ; G%HId(dl)%JsgB = G%HId(dl)%jsg
416+
if (G%symmetric) then
417+
G%HId(dl)%IscB = G%HId(dl)%isc-1 ; G%HId(dl)%JscB = G%HId(dl)%jsc-1
418+
G%HId(dl)%IsdB = G%HId(dl)%isd-1 ; G%HId(dl)%JsdB = G%HId(dl)%jsd-1
419+
G%HId(dl)%IsgB = G%HId(dl)%isg-1 ; G%HId(dl)%JsgB = G%HId(dl)%jsg-1
420+
endif
421+
G%HId(dl)%IecB = G%HId(dl)%iec ; G%HId(dl)%JecB = G%HId(dl)%jec
422+
G%HId(dl)%IedB = G%HId(dl)%ied ; G%HId(dl)%JedB = G%HId(dl)%jed
423+
G%HId(dl)%IegB = G%HId(dl)%ieg ; G%HId(dl)%JegB = G%HId(dl)%jeg
424+
enddo
421425

422426
end subroutine MOM_grid_init
423427

0 commit comments

Comments
 (0)