22 module drifters_core_mod
28 public :: drifters_core_type, drifters_core_new, drifters_core_del, drifters_core_set_ids
29 public :: drifters_core_remove_and_add, drifters_core_set_positions,
assignment(=)
30 public :: drifters_core_print, drifters_core_resize
33 integer,
parameter,
private :: MAX_STR_LEN = 128
35 #include<file_version.h>
41 type drifters_core_type
42 integer(kind=i8_kind) :: it
46 integer,
allocatable :: ids(:)
47 real ,
allocatable :: positions(:,:)
48 end type drifters_core_type
52 interface assignment(=)
53 module procedure drifters_core_copy_new
62 subroutine drifters_core_new(self, nd, npdim, ermesg)
63 type(drifters_core_type) :: self
64 integer,
intent(in) :: nd
65 integer,
intent(in) :: npdim
66 character(*),
intent(out) :: ermesg
71 call drifters_core_del(self, ermesg)
73 allocate(self%positions(nd, npdim), stat=iflag)
74 if(iflag/=0) ier = ier + 1
77 allocate(self%ids(npdim), stat=iflag)
78 if(iflag/=0) ier = ier + 1
79 self%ids = (/(i, i=1,npdim)/)
84 if(ier/=0) ermesg =
'drifters::ERROR in drifters_core_new'
85 end subroutine drifters_core_new
89 subroutine drifters_core_del(self, ermesg)
90 type(drifters_core_type) :: self
91 character(*),
intent(out) :: ermesg
99 if(
allocated(self%positions))
deallocate(self%positions, stat=iflag)
100 if(iflag/=0) ier = ier + 1
101 if(
allocated(self%ids))
deallocate(self%ids, stat=iflag)
102 if(iflag/=0) ier = ier + 1
104 if(ier/=0) ermesg =
'drifters::ERROR in drifters_core_del'
105 end subroutine drifters_core_del
108 subroutine drifters_core_copy_new(new_instance, old_instance)
110 type(drifters_core_type),
intent(inout) :: new_instance
111 type(drifters_core_type),
intent(in) :: old_instance
113 character(len=MAX_STR_LEN) :: ermesg
116 call drifters_core_del(new_instance, ermesg)
117 if(ermesg/=
'')
return
119 new_instance%it = old_instance%it
120 new_instance%nd = old_instance%nd
121 new_instance%np = old_instance%np
122 new_instance%npdim = old_instance%npdim
123 allocate(new_instance%ids(
size(old_instance%ids) ))
124 new_instance%ids = old_instance%ids
125 allocate(new_instance%positions(
size(old_instance%positions,1), &
126 &
size(old_instance%positions,2) ))
127 new_instance%positions = old_instance%positions
129 end subroutine drifters_core_copy_new
131 subroutine drifters_core_resize(self, npdim, ermesg)
132 type(drifters_core_type) :: self
133 integer,
intent(in) :: npdim
134 character(*),
intent(out) :: ermesg
135 integer ier, iflag, i
137 real ,
allocatable :: positions(:,:)
138 integer,
allocatable :: ids(:)
142 if(npdim <= self%npdim)
return
145 allocate(positions(self%nd, self%np), stat=iflag)
146 allocate( ids(self%np), stat=iflag)
148 positions = self%positions(:, 1:self%np)
149 ids = self%ids(1:self%np)
151 deallocate(self%positions, stat=iflag)
152 deallocate(self%ids , stat=iflag)
154 allocate(self%positions(self%nd, npdim), stat=iflag)
155 allocate(self%ids(npdim), stat=iflag)
158 self%ids = (/ (i, i=1,npdim) /)
159 self%positions(:, 1:self%np) = positions
162 if(ier/=0) ermesg =
'drifters::ERROR in drifters_core_resize'
163 end subroutine drifters_core_resize
166 subroutine drifters_core_set_positions(self, positions, ermesg)
167 type(drifters_core_type) :: self
168 real,
intent(in) :: positions(:,:)
169 character(*),
intent(out) :: ermesg
173 self%np = min(self%npdim,
size(positions, 2))
174 self%positions(:,1:self%np) = positions(:,1:self%np)
175 self%it = self%it + 1
176 if(ier/=0) ermesg =
'drifters::ERROR in drifters_core_set_positions'
177 end subroutine drifters_core_set_positions
180 subroutine drifters_core_set_ids(self1, ids1, ermesg1)
181 type(drifters_core_type) :: self1
182 integer,
intent(in) :: ids1(:)
183 character(*),
intent(out) :: ermesg1
187 np = min(self1%npdim,
size(ids1))
188 self1%ids(1:np) = ids1(1:np)
189 if(ier/=0) ermesg1 =
'drifters::ERROR in drifters_core_set_ids'
190 end subroutine drifters_core_set_ids
193 subroutine drifters_core_remove_and_add(self, indices_to_remove_in, &
194 & ids_to_add, positions_to_add, &
196 type(drifters_core_type) :: self
197 integer,
intent(in ) :: indices_to_remove_in(:)
198 integer,
intent(in ) :: ids_to_add(:)
199 real ,
intent(in ) :: positions_to_add(:,:)
200 character(*),
intent(out) :: ermesg
201 integer ier, np_add, np_remove, i, j, n_diff
202 integer indices_to_remove(size(indices_to_remove_in))
203 external qksrt_quicksort
208 indices_to_remove = indices_to_remove_in
209 np_remove =
size(indices_to_remove)
210 np_add =
size(ids_to_add, 1)
211 n_diff = np_add - np_remove
214 if(self%np + n_diff < 0)
then
215 ermesg =
'drifters::ERROR attempting to remove more elements than there are elements in '// &
216 &
'drifters_core_remove_and_add'
221 if(self%np + n_diff > self%npdim) &
222 &
call drifters_core_resize(self, int(1.2*(self%np + n_diff))+1, ermesg)
224 do i = 1, min(np_add, np_remove)
225 j = indices_to_remove(i)
226 self%ids(j) = ids_to_add(i)
227 self%positions(:,j) = positions_to_add(:,i)
233 self%ids( self%np+1:self%np+n_diff) = ids_to_add( np_remove+1:np_add)
234 self%positions(:, self%np+1:self%np+n_diff) = positions_to_add(:,np_remove+1:np_add)
236 self%np = self%np + n_diff
238 else if(n_diff < 0)
then
244 call qksrt_quicksort(
size(indices_to_remove), indices_to_remove, np_add+1, np_remove)
246 do i = np_remove, np_add+1, -1
247 if(self%np <= 0)
exit
248 j = indices_to_remove(i)
249 self%ids ( j) = self%ids ( self%np)
250 self%positions(:,j) = self%positions(:,self%np)
251 self%np = self%np - 1
255 if(ier/=0) ermesg =
'drifters::ERROR in drifters_core_remove_and_add'
256 end subroutine drifters_core_remove_and_add
259 subroutine drifters_core_print(self1, ermesg1)
260 type(drifters_core_type) :: self1
261 character(*),
intent(out) :: ermesg1
265 print
'(a,i10,a,i6,a,i6,a,i4,a,i4,a,i4)',
'it=',self1%it, &
266 &
' np=', self1%np,
' npdim=', self1%npdim
268 print *,
'ids and positions:'
270 print *,self1%ids(j), self1%positions(:,j)
273 end subroutine drifters_core_print
276 end module drifters_core_mod