← back to index

src/framework/MOM_hor_index.F90

portedportable, not yet portedexecuted, not portableexecutable, not hit by this run

1! This file is part of MOM6, the Modular Ocean Model version 6.
2! See the LICENSE file for licensing information.
3! SPDX-License-Identifier: Apache-2.0
4
5!> Defines the horizontal index type (hor_index_type) used for providing index ranges
6module MOM_hor_index
7
8use MOM_domains, only : MOM_domain_type, get_domain_extent, get_global_shape
9use MOM_error_handler, only : MOM_error, MOM_mesg, FATAL
10use MOM_file_parser, only : get_param, log_param, log_version, param_file_type
11
12implicit none ; private
13
14public :: hor_index_init, assignment(=)
15public :: rotate_hor_index
16
17!> Container for horizontal index ranges for data, computational and global domains
18type, public :: hor_index_type
19 integer :: isc !< The start i-index of cell centers within the computational domain
20 integer :: iec !< The end i-index of cell centers within the computational domain
21 integer :: jsc !< The start j-index of cell centers within the computational domain
22 integer :: jec !< The end j-index of cell centers within the computational domain
23
24 integer :: isd !< The start i-index of cell centers within the data domain
25 integer :: ied !< The end i-index of cell centers within the data domain
26 integer :: jsd !< The start j-index of cell centers within the data domain
27 integer :: jed !< The end j-index of cell centers within the data domain
28
29 integer :: isg !< The start i-index of cell centers within the global domain
30 integer :: ieg !< The end i-index of cell centers within the global domain
31 integer :: jsg !< The start j-index of cell centers within the global domain
32 integer :: jeg !< The end j-index of cell centers within the global domain
33
34 integer :: IscB !< The start i-index of cell vertices within the computational domain
35 integer :: IecB !< The end i-index of cell vertices within the computational domain
36 integer :: JscB !< The start j-index of cell vertices within the computational domain
37 integer :: JecB !< The end j-index of cell vertices within the computational domain
38
39 integer :: IsdB !< The start i-index of cell vertices within the data domain
40 integer :: IedB !< The end i-index of cell vertices within the data domain
41 integer :: JsdB !< The start j-index of cell vertices within the data domain
42 integer :: JedB !< The end j-index of cell vertices within the data domain
43
44 integer :: IsgB !< The start i-index of cell vertices within the global domain
45 integer :: IegB !< The end i-index of cell vertices within the global domain
46 integer :: JsgB !< The start j-index of cell vertices within the global domain
47 integer :: JegB !< The end j-index of cell vertices within the global domain
48
49 integer :: idg_offset !< The offset between the corresponding global and local i-indices.
50 integer :: jdg_offset !< The offset between the corresponding global and local j-indices.
51 logical :: symmetric !< True if symmetric memory is used.
52
53 integer :: niglobal !< The global number of h-cells in the i-direction
54 integer :: njglobal !< The global number of h-cells in the j-direction
55
56 integer :: turns !< Number of quarter-turn rotations from input to model
57end type hor_index_type
58
59!> Copy the contents of one horizontal index type into another
60interface assignment(=) ; module procedure HIT_assign ; end interface
61
62contains
63
64!> Sets various index values in a hor_index_type.
652subroutine hor_index_init(Domain, HI, param_file, local_indexing, index_offset)
66 type(MOM_domain_type), intent(in) :: Domain !< The MOM domain from which to extract information.
67 type(hor_index_type), intent(inout) :: HI !< A horizontal index type to populate with data
68 type(param_file_type), optional, intent(in) :: param_file !< Parameter file handle
69 logical, optional, intent(in) :: local_indexing !< If true, all tracer data domains start at 1
70 integer, optional, intent(in) :: index_offset !< A fixed additional offset to all indices
71
72! This include declares and sets the variable "version".
73#include "version_variable.h"
74
75 ! get_domain_extent ensures that domains start at 1 for compatibility between
76 ! static and dynamically allocated arrays.
77 call get_domain_extent(Domain, HI%isc, HI%iec, HI%jsc, HI%jec, &
78 HI%isd, HI%ied, HI%jsd, HI%jed, &
79 HI%isg, HI%ieg, HI%jsg, HI%jeg, &
80 HI%idg_offset, HI%jdg_offset, HI%symmetric, &
812 local_indexing=local_indexing)
822 call get_global_shape(Domain, HI%niglobal, HI%njglobal)
83
84 ! Read all relevant parameters and write them to the model log.
852 if (present(param_file)) &
86 call log_version(param_file, "MOM_hor_index", version, &
871 "Sets the horizontal array index types.", all_default=.true.)
88
892 HI%IscB = HI%isc ; HI%JscB = HI%jsc
902 HI%IsdB = HI%isd ; HI%JsdB = HI%jsd
912 HI%IsgB = HI%isg ; HI%JsgB = HI%jsg
922 if (HI%symmetric) then
932 HI%IscB = HI%isc-1 ; HI%JscB = HI%jsc-1
942 HI%IsdB = HI%isd-1 ; HI%JsdB = HI%jsd-1
952 HI%IsgB = HI%isg-1 ; HI%JsgB = HI%jsg-1
96 endif
972 HI%IecB = HI%iec ; HI%JecB = HI%jec
982 HI%IedB = HI%ied ; HI%JedB = HI%jed
992 HI%IegB = HI%ieg ; HI%JegB = HI%jeg
100
1012 HI%turns = 0
1022end subroutine hor_index_init
103
104!> HIT_assign copies one hor_index_type into another. It is accessed via an
105!! assignment (=) operator.
1060subroutine HIT_assign(HI1, HI2)
107 type(hor_index_type), intent(out) :: HI1 !< Horizontal index type to copy to
108 type(hor_index_type), intent(in) :: HI2 !< Horizontal index type to copy from
109 ! This subroutine copies all components of the horizontal array index type
110 ! variable on the RHS (HI2) to the variable on the LHS (HI1).
111
1120 HI1%isc = HI2%isc ; HI1%iec = HI2%iec ; HI1%jsc = HI2%jsc ; HI1%jec = HI2%jec
1130 HI1%isd = HI2%isd ; HI1%ied = HI2%ied ; HI1%jsd = HI2%jsd ; HI1%jed = HI2%jed
1140 HI1%isg = HI2%isg ; HI1%ieg = HI2%ieg ; HI1%jsg = HI2%jsg ; HI1%jeg = HI2%jeg
115
1160 HI1%IscB = HI2%IscB ; HI1%IecB = HI2%IecB ; HI1%JscB = HI2%JscB ; HI1%JecB = HI2%JecB
1170 HI1%IsdB = HI2%IsdB ; HI1%IedB = HI2%IedB ; HI1%JsdB = HI2%JsdB ; HI1%JedB = HI2%JedB
1180 HI1%IsgB = HI2%IsgB ; HI1%IegB = HI2%IegB ; HI1%JsgB = HI2%JsgB ; HI1%JegB = HI2%JegB
119
1200 HI1%niglobal = HI2%niglobal ; HI1%njglobal = HI2%njglobal
1210 HI1%idg_offset = HI2%idg_offset ; HI1%jdg_offset = HI2%jdg_offset
1220 HI1%symmetric = HI2%symmetric
1230 HI1%turns = HI2%turns
1240end subroutine HIT_assign
125
126!> Rotate the horizontal index ranges from the input to the output map.
1270subroutine rotate_hor_index(HI_in, turns, HI)
128 type(hor_index_type), intent(in) :: HI_in !< Unrotated horizontal indices
129 integer, intent(in) :: turns !< Number of quarter turns
130 type(hor_index_type), intent(inout) :: HI !< Rotated horizontal indices
131
1320 if (modulo(turns, 2) /= 0) then
1330 HI%isc = HI_in%jsc
1340 HI%iec = HI_in%jec
1350 HI%jsc = HI_in%isc
1360 HI%jec = HI_in%iec
1370 HI%isd = HI_in%jsd
1380 HI%ied = HI_in%jed
1390 HI%jsd = HI_in%isd
1400 HI%jed = HI_in%ied
1410 HI%isg = HI_in%jsg
1420 HI%ieg = HI_in%jeg
1430 HI%jsg = HI_in%isg
1440 HI%jeg = HI_in%ieg
145
1460 HI%IscB = HI_in%JscB
1470 HI%IecB = HI_in%JecB
1480 HI%JscB = HI_in%IscB
1490 HI%JecB = HI_in%IecB
1500 HI%IsdB = HI_in%JsdB
1510 HI%IedB = HI_in%JedB
1520 HI%JsdB = HI_in%IsdB
1530 HI%JedB = HI_in%IedB
1540 HI%IsgB = HI_in%JsgB
1550 HI%IegB = HI_in%JegB
1560 HI%JsgB = HI_in%IsgB
1570 HI%JegB = HI_in%IegB
158
1590 HI%niglobal = HI_in%njglobal
1600 HI%njglobal = HI_in%niglobal
1610 HI%idg_offset = HI_in%jdg_offset
1620 HI%jdg_offset = HI_in%idg_offset
163
1640 HI%symmetric = HI_in%symmetric
165 else
1660 HI = HI_in
167 endif
1680 HI%turns = HI_in%turns + turns
1690end subroutine rotate_hor_index
170
171!> \namespace mom_hor_index
172!!
173!! The hor_index_type provides the declarations and loop ranges for almost all data with horizontal extent.
174!!
175!! Declarations and loop ranges should always be coded with the symmetric memory model in mind.
176!! The non-symmetric memory mode will then also work, albeit with a different (less efficient) communication pattern.
177!!
178!! Using the hor_index_type HI:
179!! - declaration of h-point data is of the form `h(HI%%isd:HI%%ied,HI%%jsd:HI%%jed)`
180!! - declaration of q-point data is of the form `q(HI%%IsdB:HI%%IedB,HI%%JsdB:HI%%JedB)`
181!! - declaration of u-point data is of the form `u(HI%%IsdB:HI%%IedB,HI%%jsd:HI%%jed)`
182!! - declaration of v-point data is of the form `v(HI%%isd:HI%%ied,HI%%JsdB:HI%%JedB)`.
183!!
184!! For more detail explanation of horizontal indexing see \ref Horizontal_Indexing.
185
186
1870end module MOM_hor_index