MOM6
MOM_safe_alloc.F90
1 !> Convenience functions for safely allocating memory without
2 !! accidentally reallocating pointer and causing memory leaks.
4 
5 ! This file is part of MOM6. See LICENSE.md for the license.
6 
7 implicit none ; private
8 
10 
11 !> Allocate a pointer to a 1-d, 2-d or 3-d array
12 interface safe_alloc_ptr
13  module procedure safe_alloc_ptr_3d_3arg, safe_alloc_ptr_3d_6arg, safe_alloc_ptr_2d_2arg
14  module procedure safe_alloc_ptr_3d, safe_alloc_ptr_2d, safe_alloc_ptr_1d
15 end interface safe_alloc_ptr
16 
17 !> Allocate a 2-d or 3-d allocatable array
19  module procedure safe_alloc_allocatable_3d, safe_alloc_allocatable_2d
20  module procedure safe_alloc_allocatable_3d_6arg
21 end interface safe_alloc_alloc
22 
23 ! This combined interface might work with a later version of Fortran, but
24 ! it fails with the gnu F90 compiler.
25 !
26 ! interface safe_alloc
27 ! module procedure safe_alloc_ptr_3d_2arg, safe_alloc_ptr_2d_2arg
28 ! module procedure safe_alloc_ptr_3d, safe_alloc_ptr_2d, safe_alloc_ptr_1d
29 ! module procedure safe_alloc_allocatable_3d, safe_alloc_allocatable_2d
30 ! end interface safe_alloc
31 
32 contains
33 
34 !> Allocate a pointer to a 1-d array
35 subroutine safe_alloc_ptr_1d(ptr, i1, i2)
36  real, dimension(:), pointer :: ptr !< A pointer to allocate
37  integer, intent(in) :: i1 !< The size of the array, or its starting index if i2 is present
38  integer, optional, intent(in) :: i2 !< The ending index of the array
39  if (.not.associated(ptr)) then
40  if (present(i2)) then
41  allocate(ptr(i1:i2))
42  else
43  allocate(ptr(i1))
44  endif
45  ptr(:) = 0.0
46  endif
47 end subroutine safe_alloc_ptr_1d
48 
49 !> Allocate a pointer to a 2-d array based on its dimension sizes
50 subroutine safe_alloc_ptr_2d_2arg(ptr, ni, nj)
51  real, dimension(:,:), pointer :: ptr !< A pointer to allocate
52  integer, intent(in) :: ni !< The size of the 1st dimension of the array
53  integer, intent(in) :: nj !< The size of the 2nd dimension of the array
54  if (.not.associated(ptr)) then
55  allocate(ptr(ni,nj))
56  ptr(:,:) = 0.0
57  endif
58 end subroutine safe_alloc_ptr_2d_2arg
59 
60 !> Allocate a pointer to a 3-d array based on its dimension sizes
61 subroutine safe_alloc_ptr_3d_3arg(ptr, ni, nj, nk)
62  real, dimension(:,:,:), pointer :: ptr !< A pointer to allocate
63  integer, intent(in) :: ni !< The size of the 1st dimension of the array
64  integer, intent(in) :: nj !< The size of the 2nd dimension of the array
65  integer, intent(in) :: nk !< The size of the 3rd dimension of the array
66  if (.not.associated(ptr)) then
67  allocate(ptr(ni,nj,nk))
68  ptr(:,:,:) = 0.0
69  endif
70 end subroutine safe_alloc_ptr_3d_3arg
71 
72 !> Allocate a pointer to a 2-d array based on its index starting and ending values
73 subroutine safe_alloc_ptr_2d(ptr, is, ie, js, je)
74  real, dimension(:,:), pointer :: ptr !< A pointer to allocate
75  integer, intent(in) :: is !< The start index to allocate for the 1st dimension
76  integer, intent(in) :: ie !< The end index to allocate for the 1st dimension
77  integer, intent(in) :: js !< The start index to allocate for the 2nd dimension
78  integer, intent(in) :: je !< The end index to allocate for the 2nd dimension
79  if (.not.associated(ptr)) then
80  allocate(ptr(is:ie,js:je))
81  ptr(:,:) = 0.0
82  endif
83 end subroutine safe_alloc_ptr_2d
84 
85 !> Allocate a pointer to a 3-d array based on its index starting and ending values
86 subroutine safe_alloc_ptr_3d(ptr, is, ie, js, je, nk)
87  real, dimension(:,:,:), pointer :: ptr !< A pointer to allocate
88  integer, intent(in) :: is !< The start index to allocate for the 1st dimension
89  integer, intent(in) :: ie !< The end index to allocate for the 1st dimension
90  integer, intent(in) :: js !< The start index to allocate for the 2nd dimension
91  integer, intent(in) :: je !< The end index to allocate for the 2nd dimension
92  integer, intent(in) :: nk !< The size to allocate for the 3rd dimension
93  if (.not.associated(ptr)) then
94  allocate(ptr(is:ie,js:je,nk))
95  ptr(:,:,:) = 0.0
96  endif
97 end subroutine safe_alloc_ptr_3d
98 
99 !> Allocate a pointer to a 3-d array based on its index starting and ending values
100 subroutine safe_alloc_ptr_3d_6arg(ptr, is, ie, js, je, ks, ke)
101  real, dimension(:,:,:), pointer :: ptr !< A pointer to allocate
102  integer, intent(in) :: is !< The start index to allocate for the 1st dimension
103  integer, intent(in) :: ie !< The end index to allocate for the 1st dimension
104  integer, intent(in) :: js !< The start index to allocate for the 2nd dimension
105  integer, intent(in) :: je !< The end index to allocate for the 2nd dimension
106  integer, intent(in) :: ks !< The start index to allocate for the 3rd dimension
107  integer, intent(in) :: ke !< The end index to allocate for the 3rd dimension
108  if (.not.associated(ptr)) then
109  allocate(ptr(is:ie,js:je,ks:ke))
110  ptr(:,:,:) = 0.0
111  endif
112 end subroutine safe_alloc_ptr_3d_6arg
113 
114 
115 !> Allocate a 2-d allocatable array based on its index starting and ending values
116 subroutine safe_alloc_allocatable_2d(ptr, is, ie, js, je)
117  real, dimension(:,:), allocatable :: ptr !< An allocatable array to allocate
118  integer, intent(in) :: is !< The start index to allocate for the 1st dimension
119  integer, intent(in) :: ie !< The end index to allocate for the 1st dimension
120  integer, intent(in) :: js !< The start index to allocate for the 2nd dimension
121  integer, intent(in) :: je !< The end index to allocate for the 2nd dimension
122  if (.not.allocated(ptr)) then
123  allocate(ptr(is:ie,js:je))
124  ptr(:,:) = 0.0
125  endif
126 end subroutine safe_alloc_allocatable_2d
127 
128 !> Allocate a 3-d allocatable array based on its index starting and ending values
129 !! and k-index size
130 subroutine safe_alloc_allocatable_3d(ptr, is, ie, js, je, nk)
131  real, dimension(:,:,:), allocatable :: ptr !< An allocatable array to allocate
132  integer, intent(in) :: is !< The start index to allocate for the 1st dimension
133  integer, intent(in) :: ie !< The end index to allocate for the 1st dimension
134  integer, intent(in) :: js !< The start index to allocate for the 2nd dimension
135  integer, intent(in) :: je !< The end index to allocate for the 2nd dimension
136  integer, intent(in) :: nk !< The size to allocate for the 3rd dimension
137  if (.not.allocated(ptr)) then
138  allocate(ptr(is:ie,js:je,nk))
139  ptr(:,:,:) = 0.0
140  endif
141 end subroutine safe_alloc_allocatable_3d
142 
143 !> Allocate a 3-d allocatable array based on its 6 index starting and ending values
144 subroutine safe_alloc_allocatable_3d_6arg(ptr, is, ie, js, je, ks, ke)
145  real, dimension(:,:,:), allocatable :: ptr !< An allocatable array to allocate
146  integer, intent(in) :: is !< The start index to allocate for the 1st dimension
147  integer, intent(in) :: ie !< The end index to allocate for the 1st dimension
148  integer, intent(in) :: js !< The start index to allocate for the 2nd dimension
149  integer, intent(in) :: je !< The end index to allocate for the 2nd dimension
150  integer, intent(in) :: ks !< The start index to allocate for the 3rd dimension
151  integer, intent(in) :: ke !< The end index to allocate for the 3rd dimension
152  if (.not.allocated(ptr)) then
153  allocate(ptr(is:ie,js:je,ks:ke))
154  ptr(:,:,:) = 0.0
155  endif
156 end subroutine safe_alloc_allocatable_3d_6arg
157 
158 end module mom_safe_alloc
mom_safe_alloc
Convenience functions for safely allocating memory without accidentally reallocating pointer and caus...
Definition: MOM_safe_alloc.F90:3
mom_safe_alloc::safe_alloc_alloc
Allocate a 2-d or 3-d allocatable array.
Definition: MOM_safe_alloc.F90:18
mom_safe_alloc::safe_alloc_ptr
Allocate a pointer to a 1-d, 2-d or 3-d array.
Definition: MOM_safe_alloc.F90:12