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 | |
| 6 | module MOM_hor_index | |
| 7 | ||
| 8 | use MOM_domains, only : MOM_domain_type, get_domain_extent, get_global_shape | |
| 9 | use MOM_error_handler, only : MOM_error, MOM_mesg, FATAL | |
| 10 | use MOM_file_parser, only : get_param, log_param, log_version, param_file_type | |
| 11 | ||
| 12 | implicit none ; private | |
| 13 | ||
| 14 | public :: hor_index_init, assignment(=) | |
| 15 | public :: rotate_hor_index | |
| 16 | ||
| 17 | !> Container for horizontal index ranges for data, computational and global domains | |
| 18 | type, 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 | |
| 57 | end type hor_index_type | |
| 58 | ||
| 59 | !> Copy the contents of one horizontal index type into another | |
| 60 | interface assignment(=) ; module procedure HIT_assign ; end interface | |
| 61 | ||
| 62 | contains | |
| 63 | ||
| 64 | !> Sets various index values in a hor_index_type. | |
| 65 | 2 | subroutine 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, & | |
| 81 | 2 | local_indexing=local_indexing) |
| 82 | 2 | call get_global_shape(Domain, HI%niglobal, HI%njglobal) |
| 83 | ||
| 84 | ! Read all relevant parameters and write them to the model log. | |
| 85 | 2 | if (present(param_file)) & |
| 86 | call log_version(param_file, "MOM_hor_index", version, & | |
| 87 | 1 | "Sets the horizontal array index types.", all_default=.true.) |
| 88 | ||
| 89 | 2 | HI%IscB = HI%isc ; HI%JscB = HI%jsc |
| 90 | 2 | HI%IsdB = HI%isd ; HI%JsdB = HI%jsd |
| 91 | 2 | HI%IsgB = HI%isg ; HI%JsgB = HI%jsg |
| 92 | 2 | if (HI%symmetric) then |
| 93 | 2 | HI%IscB = HI%isc-1 ; HI%JscB = HI%jsc-1 |
| 94 | 2 | HI%IsdB = HI%isd-1 ; HI%JsdB = HI%jsd-1 |
| 95 | 2 | HI%IsgB = HI%isg-1 ; HI%JsgB = HI%jsg-1 |
| 96 | endif | |
| 97 | 2 | HI%IecB = HI%iec ; HI%JecB = HI%jec |
| 98 | 2 | HI%IedB = HI%ied ; HI%JedB = HI%jed |
| 99 | 2 | HI%IegB = HI%ieg ; HI%JegB = HI%jeg |
| 100 | ||
| 101 | 2 | HI%turns = 0 |
| 102 | 2 | end subroutine hor_index_init |
| 103 | ||
| 104 | !> HIT_assign copies one hor_index_type into another. It is accessed via an | |
| 105 | !! assignment (=) operator. | |
| 106 | 0 | subroutine 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 | ||
| 112 | 0 | HI1%isc = HI2%isc ; HI1%iec = HI2%iec ; HI1%jsc = HI2%jsc ; HI1%jec = HI2%jec |
| 113 | 0 | HI1%isd = HI2%isd ; HI1%ied = HI2%ied ; HI1%jsd = HI2%jsd ; HI1%jed = HI2%jed |
| 114 | 0 | HI1%isg = HI2%isg ; HI1%ieg = HI2%ieg ; HI1%jsg = HI2%jsg ; HI1%jeg = HI2%jeg |
| 115 | ||
| 116 | 0 | HI1%IscB = HI2%IscB ; HI1%IecB = HI2%IecB ; HI1%JscB = HI2%JscB ; HI1%JecB = HI2%JecB |
| 117 | 0 | HI1%IsdB = HI2%IsdB ; HI1%IedB = HI2%IedB ; HI1%JsdB = HI2%JsdB ; HI1%JedB = HI2%JedB |
| 118 | 0 | HI1%IsgB = HI2%IsgB ; HI1%IegB = HI2%IegB ; HI1%JsgB = HI2%JsgB ; HI1%JegB = HI2%JegB |
| 119 | ||
| 120 | 0 | HI1%niglobal = HI2%niglobal ; HI1%njglobal = HI2%njglobal |
| 121 | 0 | HI1%idg_offset = HI2%idg_offset ; HI1%jdg_offset = HI2%jdg_offset |
| 122 | 0 | HI1%symmetric = HI2%symmetric |
| 123 | 0 | HI1%turns = HI2%turns |
| 124 | 0 | end subroutine HIT_assign |
| 125 | ||
| 126 | !> Rotate the horizontal index ranges from the input to the output map. | |
| 127 | 0 | subroutine 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 | ||
| 132 | 0 | if (modulo(turns, 2) /= 0) then |
| 133 | 0 | HI%isc = HI_in%jsc |
| 134 | 0 | HI%iec = HI_in%jec |
| 135 | 0 | HI%jsc = HI_in%isc |
| 136 | 0 | HI%jec = HI_in%iec |
| 137 | 0 | HI%isd = HI_in%jsd |
| 138 | 0 | HI%ied = HI_in%jed |
| 139 | 0 | HI%jsd = HI_in%isd |
| 140 | 0 | HI%jed = HI_in%ied |
| 141 | 0 | HI%isg = HI_in%jsg |
| 142 | 0 | HI%ieg = HI_in%jeg |
| 143 | 0 | HI%jsg = HI_in%isg |
| 144 | 0 | HI%jeg = HI_in%ieg |
| 145 | ||
| 146 | 0 | HI%IscB = HI_in%JscB |
| 147 | 0 | HI%IecB = HI_in%JecB |
| 148 | 0 | HI%JscB = HI_in%IscB |
| 149 | 0 | HI%JecB = HI_in%IecB |
| 150 | 0 | HI%IsdB = HI_in%JsdB |
| 151 | 0 | HI%IedB = HI_in%JedB |
| 152 | 0 | HI%JsdB = HI_in%IsdB |
| 153 | 0 | HI%JedB = HI_in%IedB |
| 154 | 0 | HI%IsgB = HI_in%JsgB |
| 155 | 0 | HI%IegB = HI_in%JegB |
| 156 | 0 | HI%JsgB = HI_in%IsgB |
| 157 | 0 | HI%JegB = HI_in%IegB |
| 158 | ||
| 159 | 0 | HI%niglobal = HI_in%njglobal |
| 160 | 0 | HI%njglobal = HI_in%niglobal |
| 161 | 0 | HI%idg_offset = HI_in%jdg_offset |
| 162 | 0 | HI%jdg_offset = HI_in%idg_offset |
| 163 | ||
| 164 | 0 | HI%symmetric = HI_in%symmetric |
| 165 | else | |
| 166 | 0 | HI = HI_in |
| 167 | endif | |
| 168 | 0 | HI%turns = HI_in%turns + turns |
| 169 | 0 | end 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 | ||
| 187 | 0 | end module MOM_hor_index |