FMS  2024.03
Flexible Modeling System
fms_diag_bbox.F90
1 !***********************************************************************
2 !* GNU Lesser General Public License
3 !*
4 !* This file is part of the GFDL Flexible Modeling System (FMS).
5 !*
6 !* FMS is free software: you can redistribute it and/or modify it under
7 !* the terms of the GNU Lesser General Public License as published by
8 !* the Free Software Foundation, either version 3 of the License, or (at
9 !* your option) any later version.
10 !*
11 !* FMS is distributed in the hope that it will be useful, but WITHOUT
12 !* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 !* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 !* for more details.
15 !*
16 !* You should have received a copy of the GNU Lesser General Public
17 !* License along with FMS. If not, see <http://www.gnu.org/licenses/>.
18 !***********************************************************************
19 
20 !> @defgroup fms_diag_bbox_mod fms_diag_bbox_mod
21 !> @ingroup diag_manager
22 !> @brief fms_diag_bbox_mod defines classes encapsulating bounding boxes
23 !! and interval bounds.
24 !!
25 !> @author Miguel Zuniga
26 !!
27 !> @file
28 !> @brief File for @ref fms_diag_bbox_mod
29 !> @addtogroup fms_diag_bbox_mod
30 !> @{
31 MODULE fms_diag_bbox_mod
32 
33  USE fms_mod, ONLY: error_mesg, fatal, fms_error_handler, string
34 
35  implicit none
36 
37 !> @brief Data structure holding a 3D bounding box. It is commonlyused to
38 !! represent the interval bounds or limits of a 3D sub-array such as the
39 !! array index bounds of the spatial component a diag_manager field output
40 !! buffer array.
41  TYPE, public :: fmsdiagibounds_type
42  INTEGER :: imin !< Lower i bound.
43  INTEGER :: imax !< Upper i bound.
44  INTEGER :: jmin !< Lower j bound.
45  INTEGER :: jmax !< Upper j bound.
46  INTEGER :: kmin !< Lower k bound.
47  INTEGER :: kmax !< Upper k bound.
48  logical :: has_halos !< .True. if the buffer has halos
49  integer :: nhalo_i !< Number of halos in i
50  integer :: nhalo_j !< Number of halos in j
51  contains
52  procedure :: reset => reset_bounds
53  procedure :: reset_bounds_from_array_4d
54  procedure :: reset_bounds_from_array_5d
55  procedure :: update_bounds
56  procedure :: set_bounds
57  procedure :: rebase_input
58  procedure :: rebase_output
59  procedure :: get_imin
60  procedure :: get_imax
61  procedure :: get_jmin
62  procedure :: get_jmax
63  procedure :: get_kmin
64  procedure :: get_kmax
65  procedure :: update_index
66  END TYPE fmsdiagibounds_type
67 
68  !> @brief Data structure holding starting and ending indices in the I, J, and
69  !! K dimensions. It also has extra members related to halo sizes and updated indices
70  !! in I and J dimensions.
71  type, public :: fmsdiagboundshalos_type
72  private
73  type(fmsdiagibounds_type) :: bounds3d !< Holds starting and ending indices of
74  !! the I, J, and K dimensions
75  integer :: hi !< Halo size in the I dimension
76  integer :: hj !< Halo size in the J dimension
77  integer :: fis !< Updated starting index in the I dimension
78  integer :: fie !< Updated ending index in the I dimension
79  integer :: fjs !< Updated starting index in the J dimension
80  integer :: fje !< Updated ending index in the J dimension
81  contains
82  procedure :: get_hi
83  procedure :: get_hj
84  procedure :: get_fis
85  procedure :: get_fie
86  procedure :: get_fjs
87  procedure :: get_fje
89 
91 
92  integer, parameter :: xdimension = 1 !< Parameter defining the x dimension
93  integer, parameter :: ydimension = 2 !< Parameter defining the y dimension
94  integer, parameter :: zdimension = 3 !< Parameter defininf the z dimension
95 
96 CONTAINS
97 
98 !> @brief The PEs grid points are divided further into "blocks". This function determines if a block
99 ! has data for a given subregion and dimension
100 !! @return .true. if the a subergion is inside a block
101 logical pure function determine_if_block_is_in_region(subregion_start, subregion_end, bounds, dim)
102  integer, intent(in) :: subregion_start !< Begining of the subregion
103  integer, intent(in) :: subregion_end !< Ending of the subregion
104  type(fmsdiagibounds_type), intent(in) :: bounds !< Starting and ending of the subregion
105  integer, intent(in) :: dim !< Dimension to check
106 
107  integer :: block_start !< Begining index of the block
108  integer :: block_end !< Ending index of the block
109 
111  select case (dim)
112  case (xdimension)
113  block_start = bounds%imin
114  block_end = bounds%imax
115  case (ydimension)
116  block_start = bounds%jmin
117  block_end = bounds%jmax
118  case (zdimension)
119  block_start = bounds%kmin
120  block_end = bounds%kmax
121  end select
122 
123  if (block_start < subregion_start .and. block_end < subregion_start) then
125  return
126  endif
127 
128  if (block_start > subregion_end .and. block_end > subregion_end) then
130  return
131  endif
132 
135 
136  !> @brief Gets imin of fmsDiagIbounds_type
137  !! @return copy of integer member imin
138  pure integer function get_imin (this) result(rslt)
139  class(fmsdiagibounds_type), intent(in) :: this !< The !< ibounds instance
140  rslt = this%imin
141  end function get_imin
142 
143  !> @brief Gets imax of fmsDiagIbounds_type
144  !! @return copy of integer member imax
145  pure integer function get_imax (this) result(rslt)
146  class(fmsdiagibounds_type), intent(in) :: this !< The !< ibounds instance
147  rslt = this%imax
148  end function get_imax
149 
150  !> @brief Gets jmin of fmsDiagIbounds_type
151  !! @return copy of integer member jmin
152  pure integer function get_jmin (this) result(rslt)
153  class(fmsdiagibounds_type), intent(in) :: this !< The !< ibounds instance
154  rslt = this%jmin
155  end function get_jmin
156 
157  !> @brief Gets jmax of fmsDiagIbounds_type
158  !! @return copy of integer member jmax
159  pure integer function get_jmax (this) result(rslt)
160  class(fmsdiagibounds_type), intent(in) :: this !< The !< ibounds instance
161  rslt = this%jmax
162  end function get_jmax
163 
164 
165  !> @brief Gets kmin of fmsDiagIbounds_type
166  !! @return copy of integer member kmin
167  pure integer function get_kmin (this) result(rslt)
168  class(fmsdiagibounds_type), intent(in) :: this !< The !< ibounds instance
169  rslt = this%kmin
170  end function get_kmin
171 
172  !> @brief Gets kmax of fmsDiagIbounds_type
173  !! @return copy of integer member kmax
174  pure integer function get_kmax (this) result(rslt)
175  class(fmsdiagibounds_type), intent(in) :: this !< The !< ibounds instance
176  rslt = this%kmax
177  end function get_kmax
178 
179  !> @brief Updates the starting and ending index of a given dimension
180  subroutine update_index(this, starting_index, ending_index, dim, ignore_halos)
181  class(fmsdiagibounds_type), intent(inout) :: this !< The bounding box to update
182  integer, intent(in) :: starting_index !< Starting index to update to
183  integer, intent(in) :: ending_index !< Ending index to update to
184  integer, intent(in) :: dim !< Dimension to update
185  logical, intent(in) :: ignore_halos !< If .true. halos will be ignored
186  !! i.e output buffers can ignore halos as
187  !! they do not get updates. The indices of the
188  !! Input buffers need to add the number of halos
189  !! so math is done only on the compute domain
190 
191  integer :: nhalox !< Number of halos in x
192  integer :: nhaloy !< Number of halos in y
193 
194  if (ignore_halos) then
195  nhalox = 0
196  nhaloy = 0
197  else
198  nhalox= this%nhalo_I
199  nhaloy= this%nhalo_J
200  endif
201  select case(dim)
202  case (xdimension)
203  this%imin = starting_index + nhalox
204  this%imax = ending_index + nhalox
205  case (ydimension)
206  this%jmin = starting_index + nhaloy
207  this%jmax = ending_index + nhaloy
208  case (zdimension)
209  this%kmin = starting_index
210  this%kmax = ending_index
211  end select
212  end subroutine
213 
214  !> @brief Gets the halo size of fmsDiagBoundsHalos_type in the I dimension
215  !! @return copy of integer member hi
216  pure integer function get_hi (this) result(rslt)
217  class(fmsdiagboundshalos_type), intent(in) :: this !< Calling object
218  rslt = this%hi
219  end function get_hi
220 
221  !> @brief Gets the halo size of fmsDiagBoundsHalos_type in the J dimension
222  !! @return copy of integer member hj
223  pure integer function get_hj (this) result(rslt)
224  class(fmsdiagboundshalos_type), intent(in) :: this !< Calling object
225  rslt = this%hj
226  end function get_hj
227 
228  !> @brief Gets the updated index `fis' of fmsDiagBoundsHalos_type in the I dimension
229  !! @return copy of integer member `fis'
230  pure integer function get_fis (this) result(rslt)
231  class(fmsdiagboundshalos_type), intent(in) :: this !< Calling object
232  rslt = this%fis
233  end function get_fis
234 
235  !> @brief Gets the updated index `fie' of fmsDiagBoundsHalos_type in the I dimension
236  !! @return copy of integer member `fie'
237  pure integer function get_fie (this) result(rslt)
238  class(fmsdiagboundshalos_type), intent(in) :: this !< Calling object
239  rslt = this%fie
240  end function get_fie
241 
242  !> @brief Gets the updated index `fjs' of fmsDiagBoundsHalos_type in the I dimension
243  !! @return copy of integer member `fjs'
244  pure integer function get_fjs (this) result(rslt)
245  class(fmsdiagboundshalos_type), intent(in) :: this !< Calling object
246  rslt = this%fjs
247  end function get_fjs
248 
249  !> @brief Gets the updated index `fje' of fmsDiagBoundsHalos_type in the I dimension
250  !! @return copy of integer member `fje'
251  pure integer function get_fje (this) result(rslt)
252  class(fmsdiagboundshalos_type), intent(in) :: this !< Calling object
253  rslt = this%fje
254  end function get_fje
255 
256  !> @brief Reset the instance bounding lower and upper bounds to lower_val and upper_val, respectively.
257  SUBROUTINE reset_bounds (this, lower_val, upper_val)
258  class(fmsdiagibounds_type), target, intent(inout) :: this !< ibounds instance
259  integer, intent(in) :: lower_val !< value for the lower bounds in each dimension
260  integer, intent(in) :: upper_val !< value for the upper bounds in each dimension
261  this%imin = lower_val
262  this%jmin = lower_val
263  this%kmin = lower_val
264  this%imax = upper_val
265  this%jmax = upper_val
266  this%kmax = upper_val
267  END SUBROUTINE reset_bounds
268 
269  !> @brief Update the the first three (normally x, y, and z) min and
270  !! max boundaries (array indices) of the instance bounding box
271  !! the six specified bounds values.
272  SUBROUTINE update_bounds(this, lower_i, upper_i, lower_j, upper_j, lower_k, upper_k)
273  class(fmsdiagibounds_type), intent(inout) :: this !<The bounding box of the output field buffer inindex space.
274  INTEGER, INTENT(in) :: lower_i !< Lower i bound.
275  INTEGER, INTENT(in) :: upper_i !< Upper i bound.
276  INTEGER, INTENT(in) :: lower_j !< Lower j bound.
277  INTEGER, INTENT(in) :: upper_j !< Upper j bound.
278  INTEGER, INTENT(in) :: lower_k !< Lower k bound.
279  INTEGER, INTENT(in) :: upper_k !< Upper k bound.
280  this%imin = min(this%imin, lower_i)
281  this%imax = max(this%imax, upper_i)
282  this%jmin = min(this%jmin, lower_j)
283  this%jmax = max(this%jmax, upper_j)
284  this%kmin = min(this%kmin, lower_k)
285  this%kmax = max(this%kmax, upper_k)
286  END SUBROUTINE update_bounds
287 
288  !> @brief Sets the bounds of a bounding region
289  !! @return empty string if sucessful or error message if unsucessful
290  function set_bounds(this, field_data, lower_i, upper_i, lower_j, upper_j, lower_k, upper_k, has_halos) &
291  result(error_msg)
292  class(fmsdiagibounds_type), intent(inout) :: this !< The bounding box of the field
293  class(*), intent(in) :: field_data(:,:,:,:) !< Field data
294  INTEGER, INTENT(in) :: lower_i !< Lower i bound.
295  INTEGER, INTENT(in) :: upper_i !< Upper i bound.
296  INTEGER, INTENT(in) :: lower_j !< Lower j bound.
297  INTEGER, INTENT(in) :: upper_j !< Upper j bound.
298  INTEGER, INTENT(in) :: lower_k !< Lower k bound.
299  INTEGER, INTENT(in) :: upper_k !< Upper k bound.
300  LOGICAL, INTENT(in) :: has_halos !< .true. if the field has halos
301 
302  character(len=150) :: error_msg !< Error message to output
303 
304  integer :: nhalos_2 !< 2 times the number of halo points
305  integer :: nhalox !< Number of halos in x
306  integer :: nhaloy !< Number of halos in y
307 
308  error_msg = ""
309  this%kmin = lower_k
310  this%kmax = upper_k
311  this%has_halos = has_halos
312  this%nhalo_I = 0
313  this%nhalo_J = 0
314  if (has_halos) then
315  !upper_i-lower_i+1 is the size of the compute domain
316  !ubound(field_data,1) is the size of the data domain
317  nhalos_2 = ubound(field_data,1)-(upper_i-lower_i+1)
318  if (mod(nhalos_2, 2) .ne. 0) then
319  error_msg = "There are non-symmetric halos in the first dimension"
320  return
321  endif
322  nhalox = nhalos_2/2
323  this%nhalo_I = nhalox
324 
325  nhalos_2 = ubound(field_data,2)-(upper_j-lower_j + 1)
326  if (mod(nhalos_2, 2) .ne. 0) then
327  error_msg = "There are non-symmetric halos in the second dimension"
328  return
329  endif
330  nhaloy = nhalos_2/2
331  this%nhalo_J = nhaloy
332 
333  this%imin = 1 + nhalox
334  this%imax = ubound(field_data,1) - nhalox
335  this%jmin = 1 + nhaloy
336  this%jmax = ubound(field_data,2) - nhaloy
337  else
338  this%imin = lower_i
339  this%imax = upper_i
340  this%jmin = lower_j
341  this%jmax = upper_j
342  endif
343 
344  end function set_bounds
345  !> @brief Reset the instance bounding box with the bounds determined from the
346  !! first three dimensions of the 5D "array" argument
347  SUBROUTINE reset_bounds_from_array_4d(this, array)
348  class(fmsdiagibounds_type), INTENT(inout) :: this !< The instance of the bounding box.
349  class(*), INTENT( in), DIMENSION(:,:,:,:) :: array !< The 4D input array.
350  this%imin = lbound(array,1)
351  this%imax = ubound(array,1)
352  this%jmin = lbound(array,2)
353  this%jmax = ubound(array,2)
354  this%kmin = lbound(array,3)
355  this%kmax = ubound(array,3)
356 
357  this%has_halos = .false.
358  this%nhalo_I = 0
359  this%nhalo_J = 0
360  END SUBROUTINE reset_bounds_from_array_4d
361 
362  !> @brief Reset the instance bounding box with the bounds determined from the
363  !! first three dimensions of the 5D "array" argument
364  SUBROUTINE reset_bounds_from_array_5d(this, array)
365  class(fmsdiagibounds_type), INTENT(inout) :: this !< The instance of the bounding box.
366  CLASS(*), INTENT( in), DIMENSION(:,:,:,:,:) :: array !< The 5D input array.
367  this%imin = lbound(array,1)
368  this%imax = ubound(array,1)
369  this%jmin = lbound(array,2)
370  this%jmax = ubound(array,2)
371  this%kmin = lbound(array,3)
372  this%kmax = ubound(array,3)
373  END SUBROUTINE reset_bounds_from_array_5d
374 
375  !> @brief Updates indices based on presence/absence of input indices is, js, ks, ie, je, and ke.
376  ! Computes halo sizes in the I and J dimensions.
377  ! This routine is intended to be used in diag manager.
378  !> @return .false. if there is no error else .true.
379  function recondition_indices(indices, field, is_in, js_in, ks_in, &
380  ie_in, je_in, ke_in, err_msg) result(ierr)
381  type(fmsdiagboundshalos_type), intent(inout) :: indices !< Stores indices in order:
382  !! (/is, js, ks, ie, je, ke, hi, fis, fie, hj, fjs, fje/)
383  class(*), intent(in) :: field(:,:,:,:) !< Dummy variable; only the sizes of the first 3 dimensions are used
384  integer, intent(in), optional :: is_in, js_in, ks_in, ie_in, je_in, ke_in !< User input indices
385  character(len=*), intent(out), optional :: err_msg !< Error message to pass back to caller
386  logical :: ierr !< Error flag
387 
388  integer :: is, js, ks, ie, je, ke !< Local indices to update
389  integer :: hi !< halo size in the I dimension
390  integer :: hj !< halo size in the J dimension
391  integer :: twohi, twohj !< Temporary storages
392  integer :: fis, fie, fjs, fje !< ! Updated starting and ending indices in the I and J dimensions
393  integer :: n1, n2, n3 !< Sizes of the first 3 dimenstions indicies of the data
394 
395  ierr = .false.
396  if (present(err_msg)) err_msg = ''
397 
398  ! If is, js, or ks not present default them to 1
399  is = 1
400  js = 1
401  ks = 1
402 
403  IF ( PRESENT(is_in) ) is = is_in
404  IF ( PRESENT(js_in) ) js = js_in
405  IF ( PRESENT(ks_in) ) ks = ks_in
406 
407  n1 = SIZE(field, 1)
408  n2 = SIZE(field, 2)
409  n3 = SIZE(field, 3)
410 
411  ie = is + n1 - 1
412  je = js + n2 - 1
413  ke = ks + n3 - 1
414 
415  IF ( PRESENT(ie_in) ) ie = ie_in
416  IF ( PRESENT(je_in) ) je = je_in
417  IF ( PRESENT(ke_in) ) ke = ke_in
418 
419  twohi = n1 - (ie - is + 1)
420  IF ( mod(twohi, 2) /= 0 ) THEN
421  ierr = fms_error_handler('diag_util_mod:recondition_indices', &
422  'non-symmetric halos in first dimension', err_msg)
423  IF (ierr) RETURN
424  END IF
425 
426  twohj = n2 - (je - js + 1)
427  IF ( mod(twohj, 2) /= 0 ) THEN
428  ierr = fms_error_handler('diag_util_mod:recondition_indices', &
429  'non-symmetric halos in second dimension', err_msg)
430  IF (ierr) RETURN
431  END IF
432 
433  hi = twohi/2
434  hj = twohj/2
435 
436  ! The next line is necessary to ensure that is, ie, js, ie are relative to field(1:,1:)
437  ! But this works only when there is no windowing.
438  IF ( PRESENT(ie_in) .AND. PRESENT(je_in) ) THEN
439  is = 1 + hi
440  ie = n1 - hi
441  js = 1 + hj
442  je = n2 - hj
443  END IF
444 
445  ! Used for field, mask and rmask bounds
446  fis = 1 + hi
447  fie = n1 - hi
448  fjs = 1 + hj
449  fje = n2 - hj
450 
451  ! Update indices
452  indices%bounds3D%imin = is
453  indices%bounds3D%imax = ie
454  indices%bounds3D%jmin = js
455  indices%bounds3D%jmax = je
456  indices%bounds3D%kmin = ks
457  indices%bounds3D%kmax = ke
458  indices%hi = hi
459  indices%hj = hj
460  indices%fis = fis
461  indices%fie = fie
462  indices%fjs = fjs
463  indices%fje = fje
464  end function recondition_indices
465 
466  !> @brief Rebase the ouput bounds for a given dimension based on the starting and ending indices of
467  !! a subregion. This is for when blocking is used.
468  subroutine rebase_output(bounds_out, starting, ending, dim)
469  class(fmsdiagibounds_type), INTENT(inout) :: bounds_out !< Bounds to rebase
470  integer, intent(in) :: starting !< Starting index of the dimension
471  integer, intent(in) :: ending !< Ending index of the dimension
472  integer, intent(in) :: dim !< Dimension to update
473 
474  !> The starting index is going to be either "starting" if only a section of the
475  !! block is in the subregion or bounds_out%[]min if the whole section of the block is in the
476  !! subregion. The -starting+1 s needed so that indices start as 1 since the output buffer has
477  !! indices 1:size of a subregion
478 
479  !> The ending index is going to be either bounds_out%[]max if the whole section of the block
480  !! is in the subregion or bounds_out%[]min + size of the subregion if only a section of the
481  !! block is in the susbregion
482  select case (dim)
483  case (xdimension)
484  bounds_out%imin = max(starting, bounds_out%imin)-starting+1
485  bounds_out%imax = min(bounds_out%imax, bounds_out%imin + ending-starting)
486  case (ydimension)
487  bounds_out%jmin = max(starting, bounds_out%jmin)-starting+1
488  bounds_out%jmax = min(bounds_out%jmax, bounds_out%jmin + ending-starting)
489  case (zdimension)
490  bounds_out%kmin =max(starting, bounds_out%kmin)-starting+1
491  bounds_out%kmax = min(bounds_out%kmax, bounds_out%kmin + ending-starting)
492  end select
493  end subroutine
494 
495  !> @brief Rebase the input bounds for a given dimension based on the starting and ending indices
496  !! of a subregion. This is for when blocking is used
497  subroutine rebase_input(bounds_in, bounds, starting, ending, dim)
498  class(fmsdiagibounds_type), INTENT(inout) :: bounds_in !< Bounds to rebase
499  class(fmsdiagibounds_type), INTENT(in) :: bounds !< Original indices (i.e is_in, ie_in,
500  !! passed into diag_manager)
501  integer, intent(in) :: starting !< Starting index of the dimension
502  integer, intent(in) :: ending !< Ending index of the dimension
503  integer, intent(in) :: dim !< Dimension to update
504 
505  !> The starting index is going to be either "starting" if only a section of the
506  !! block is in the subregion or starting-bounds%imin+1 if the whole section of the block is in the
507  !! subregion.
508 
509  !> The ending index is going to be either bounds_out%[]max if the whole section of the block
510  !! is in the subregion or bounds%[]min + size of the subregion if only a section of the
511  !! block is in the susbregion
512  select case (dim)
513  case (xdimension)
514  bounds_in%imin = min(abs(starting-bounds%imin+1), starting)
515  bounds_in%imax = min(bounds_in%imax, (bounds_in%imin + ending-starting))
516  case (ydimension)
517  bounds_in%jmin = min(abs(starting-bounds%jmin+1), starting)
518  bounds_in%jmax = min(bounds_in%jmax, (bounds_in%jmin + ending-starting))
519  case (zdimension)
520  bounds_in%kmin = min(abs(starting-bounds%kmin+1), starting)
521  bounds_in%kmax = min(bounds_in%kmax, (bounds_in%kmin + ending-starting))
522  end select
523  end subroutine
524 
525  END MODULE fms_diag_bbox_mod
526  !> @}
527  ! close documentation grouping
subroutine rebase_input(bounds_in, bounds, starting, ending, dim)
Rebase the input bounds for a given dimension based on the starting and ending indices of a subregion...
logical function, public recondition_indices(indices, field, is_in, js_in, ks_in, ie_in, je_in, ke_in, err_msg)
Updates indices based on presence/absence of input indices is, js, ks, ie, je, and ke.
subroutine update_bounds(this, lower_i, upper_i, lower_j, upper_j, lower_k, upper_k)
Update the the first three (normally x, y, and z) min and max boundaries (array indices) of the insta...
integer, parameter ydimension
Parameter defining the y dimension.
pure integer function get_imin(this)
Gets imin of fmsDiagIbounds_type.
subroutine reset_bounds_from_array_4d(this, array)
Reset the instance bounding box with the bounds determined from the first three dimensions of the 5D ...
pure integer function get_fjs(this)
Gets the updated index ‘fjs’ of fmsDiagBoundsHalos_type in the I dimension.
integer, parameter xdimension
Parameter defining the x dimension.
subroutine rebase_output(bounds_out, starting, ending, dim)
Rebase the ouput bounds for a given dimension based on the starting and ending indices of a subregion...
pure integer function get_hi(this)
Gets the halo size of fmsDiagBoundsHalos_type in the I dimension.
pure integer function get_imax(this)
Gets imax of fmsDiagIbounds_type.
pure integer function get_fje(this)
Gets the updated index ‘fje’ of fmsDiagBoundsHalos_type in the I dimension.
pure integer function get_kmax(this)
Gets kmax of fmsDiagIbounds_type.
pure integer function get_fie(this)
Gets the updated index ‘fie’ of fmsDiagBoundsHalos_type in the I dimension.
logical pure function, public determine_if_block_is_in_region(subregion_start, subregion_end, bounds, dim)
The PEs grid points are divided further into "blocks". This function determines if a block.
pure integer function get_hj(this)
Gets the halo size of fmsDiagBoundsHalos_type in the J dimension.
subroutine reset_bounds(this, lower_val, upper_val)
Reset the instance bounding lower and upper bounds to lower_val and upper_val, respectively.
subroutine update_index(this, starting_index, ending_index, dim, ignore_halos)
Updates the starting and ending index of a given dimension.
subroutine reset_bounds_from_array_5d(this, array)
Reset the instance bounding box with the bounds determined from the first three dimensions of the 5D ...
pure integer function get_fis(this)
Gets the updated index ‘fis’ of fmsDiagBoundsHalos_type in the I dimension.
pure integer function get_jmin(this)
Gets jmin of fmsDiagIbounds_type.
pure integer function get_jmax(this)
Gets jmax of fmsDiagIbounds_type.
pure integer function get_kmin(this)
Gets kmin of fmsDiagIbounds_type.
integer, parameter zdimension
Parameter defininf the z dimension.
character(len=150) function set_bounds(this, field_data, lower_i, upper_i, lower_j, upper_j, lower_k, upper_k, has_halos)
Sets the bounds of a bounding region.
Data structure holding starting and ending indices in the I, J, and K dimensions. It also has extra m...
logical function, public fms_error_handler(routine, message, err_msg)
Facilitates the control of fatal error conditions.
Definition: fms.F90:525
subroutine, public error_mesg(routine, message, level)
Print notes, warnings and error messages; terminates program for warning and error messages....
Definition: fms.F90:498
Data structure holding a 3D bounding box. It is commonlyused to represent the interval bounds or limi...