24 #include <fms_platform.h> 30 #ifdef _TEST_DRIFTERS_CORE 37 #include<file_version.h> 46 integer, _allocatable :: ids(:)_null
47 real , _allocatable :: positions(:,:) _null
50 interface assignment(=)
59 integer,
intent(in) :: nd
60 integer,
intent(in) :: npdim
61 character(*),
intent(out) :: ermesg
68 allocate(self%positions(nd, npdim), stat=iflag)
69 if(iflag/=0) ier = ier + 1
72 allocate(self%ids(npdim), stat=iflag)
73 if(iflag/=0) ier = ier + 1
74 self%ids = (/(i, i=1,npdim)/)
79 if(ier/=0) ermesg =
'drifters::ERROR in drifters_core_new' 85 character(*),
intent(out) :: ermesg
93 if(_allocated(self%positions))
deallocate(self%positions, stat=iflag)
94 if(iflag/=0) ier = ier + 1
95 if(_allocated(self%ids))
deallocate(self%ids, stat=iflag)
96 if(iflag/=0) ier = ier + 1
98 if(ier/=0) ermesg =
'drifters::ERROR in drifters_core_del' 104 type(drifters_core_type),
intent(inout) :: new_instance
105 type(drifters_core_type),
intent(in) :: old_instance
107 character(len=MAX_STR_LEN) :: ermesg
111 if(ermesg/=
'')
return 113 new_instance%it = old_instance%it
114 new_instance%nd = old_instance%nd
115 new_instance%np = old_instance%np
116 new_instance%npdim = old_instance%npdim
117 allocate(new_instance%ids(
size(old_instance%ids) ))
118 new_instance%ids = old_instance%ids
119 allocate(new_instance%positions(
size(old_instance%positions,1), &
120 &
size(old_instance%positions,2) ))
121 new_instance%positions = old_instance%positions
126 type(drifters_core_type) :: self
127 integer,
intent(in) :: npdim
128 character(*),
intent(out) :: ermesg
129 integer ier, iflag, i
131 real ,
allocatable :: positions(:,:)
132 integer,
allocatable :: ids(:)
136 if(npdim <= self%npdim)
return 139 allocate(positions(self%nd, self%np), stat=iflag)
140 allocate( ids(self%np), stat=iflag)
142 positions = self%positions(:, 1:self%np)
143 ids = self%ids(1:self%np)
145 deallocate(self%positions, stat=iflag)
146 deallocate(self%ids , stat=iflag)
148 allocate(self%positions(self%nd, npdim), stat=iflag)
149 allocate(self%ids(npdim), stat=iflag)
152 self%ids = (/ (i, i=1,npdim) /)
153 self%positions(:, 1:self%np) = positions
156 if(ier/=0) ermesg =
'drifters::ERROR in drifters_core_resize' 162 real,
intent(in) :: positions(:,:)
163 character(*),
intent(out) :: ermesg
167 self%np =
min(self%npdim,
size(positions, 2))
168 self%positions(:,1:self%np) = positions(:,1:self%np)
169 self%it = self%it + 1
170 if(ier/=0) ermesg =
'drifters::ERROR in drifters_core_set_positions' 175 type(drifters_core_type) :: self
176 integer,
intent(in) :: ids(:)
177 character(*),
intent(out) :: ermesg
181 np =
min(self%npdim,
size(ids))
182 self%ids(1:np) = ids(1:np)
183 if(ier/=0) ermesg =
'drifters::ERROR in drifters_core_set_ids' 188 & ids_to_add, positions_to_add, &
191 integer,
intent(in ) :: indices_to_remove_in(:)
192 integer,
intent(in ) :: ids_to_add(:)
193 real ,
intent(in ) :: positions_to_add(:,:)
194 character(*),
intent(out) :: ermesg
195 integer ier, np_add, np_remove, i, j, n_diff
196 integer indices_to_remove(
size(indices_to_remove_in))
202 indices_to_remove = indices_to_remove_in
203 np_remove =
size(indices_to_remove)
204 np_add =
size(ids_to_add, 1)
205 n_diff = np_add - np_remove
208 if(self%np + n_diff < 0)
then 209 ermesg =
'drifters::ERROR attempting to remove more elements than there are elements in drifters_core_remove_and_add' 214 if(self%np + n_diff > self%npdim) &
217 do i = 1,
min(np_add, np_remove)
218 j = indices_to_remove(i)
219 self%ids(j) = ids_to_add(i)
220 self%positions(:,j) = positions_to_add(:,i)
226 self%ids( self%np+1:self%np+n_diff) = ids_to_add( np_remove+1:np_add)
227 self%positions(:, self%np+1:self%np+n_diff) = positions_to_add(:,np_remove+1:np_add)
229 self%np = self%np + n_diff
231 else if(n_diff < 0)
then 237 call qksrt_quicksort(
size(indices_to_remove), indices_to_remove, np_add+1, np_remove)
239 do i = np_remove, np_add+1, -1
240 if(self%np <= 0)
exit 241 j = indices_to_remove(i)
242 self%ids ( j) = self%ids ( self%np)
243 self%positions(:,j) = self%positions(:,self%np)
244 self%np = self%np - 1
248 if(ier/=0) ermesg =
'drifters::ERROR in drifters_core_remove_and_add' 253 type(drifters_core_type) :: self
254 character(*),
intent(out) :: ermesg
258 print
'(a,i10,a,i6,a,i6,a,i4,a,i4,a,i4)',
'it=',self%it, &
259 &
' np=', self%np,
' npdim=', self%npdim
261 print *,
'ids and positions:' 263 print *,self%ids(j), self%positions(:,j)
273 #ifdef _TEST_DRIFTERS_CORE 277 type(drifters_core_type) :: drf
278 integer :: ier, nd, npdim, i, j, np
279 character(128) :: ermesg
281 real ,
allocatable :: positions(:,:), positions_to_add(:,:)
287 if(ermesg/=
'') print *,ermesg
289 if(ermesg/=
'') print *,ermesg
291 if(ermesg/=
'') print *,ermesg
297 if(ermesg/=
'') print *,ermesg
301 allocate(positions(nd,np))
302 positions(1,:) = (/0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0/)
303 positions(2,:) = (/0.1, 1.1, 2.1, 3.1, 4.1, 5.1, 6.1/)
304 positions(3,:) = (/0.2, 1.2, 2.2, 3.2, 4.2, 5.2, 6.2/)
306 if(ermesg/=
'') print *,ermesg
311 allocate(positions_to_add(nd,npa))
312 positions_to_add(1,:) = (/100.0, 200.0/)
313 positions_to_add(2,:) = (/100.1, 200.1/)
314 positions_to_add(3,:) = (/100.2, 200.2/)
316 & (/ 1001, 1002 /), &
317 & positions_to_add, &
319 if(ermesg/=
'') print *,ermesg
321 deallocate(positions_to_add)
325 allocate(positions_to_add(nd,npa))
326 positions_to_add(1,:) = (/1000.0, 2000.0, 3000.0/)
327 positions_to_add(2,:) = (/1000.1, 2000.1, 3000.1/)
328 positions_to_add(3,:) = (/1000.2, 2000.2, 3000.2/)
330 & (/ 1003, 1004, 1005 /), &
331 & positions_to_add, &
333 if(ermesg/=
'') print *,ermesg
335 deallocate(positions_to_add)
339 allocate(positions_to_add(nd,npa))
340 positions_to_add(1,:) = (/100.0, 200.0, 300.0, 400.0, 500.0, 600.0, 700.0, 800.0, 900.0, 10000.0/)
341 positions_to_add(2,:) = (/100.1, 200.1, 300.1, 400.1, 500.1, 600.1, 700.1, 800.1, 900.1, 10000.1/)
342 positions_to_add(3,:) = (/100.2, 200.2, 300.2, 400.2, 500.2, 600.2, 700.2, 800.2, 900.2, 10000.2/)
344 & (/ (1010+i, i=1,npa) /), &
345 & positions_to_add, &
347 if(ermesg/=
'') print *,ermesg
349 deallocate(positions_to_add)
subroutine drifters_core_set_ids(self, ids, ermesg)
recursive subroutine qksrt_quicksort(n, list, start, end)
subroutine, public drifters_core_set_positions(self, positions, ermesg)
subroutine, public drifters_core_new(self, nd, npdim, ermesg)
subroutine drifters_core_copy_new(new_instance, old_instance)
subroutine, public drifters_core_remove_and_add(self, indices_to_remove_in, ids_to_add, positions_to_add, ermesg)
integer, parameter, private max_str_len
subroutine drifters_core_resize(self, npdim, ermesg)
************************************************************************GNU Lesser General Public License **This file is part of the GFDL Flexible Modeling System(FMS). ! *! *FMS is free software without even the implied warranty of MERCHANTABILITY or *FITNESS FOR A PARTICULAR PURPOSE See the GNU General Public License *for more details **You should have received a copy of the GNU Lesser General Public *License along with FMS If see< http:! ***********************************************************************subroutine READ_RECORD_CORE_(unit, field, nwords, data, start, axsiz) integer, intent(in) ::unit type(fieldtype), intent(in) ::field integer, intent(in) ::nwords MPP_TYPE_, intent(inout) ::data(nwords) integer, intent(in) ::start(:), axsiz(:) integer(SHORT_KIND) ::i2vals(nwords)!rab used in conjunction with transfer intrinsic to determine size of a variable integer(KIND=1) ::one_byte(8) integer ::word_sz!#ifdef __sgi integer(INT_KIND) ::ivals(nwords) real(FLOAT_KIND) ::rvals(nwords)!#else! integer ::ivals(nwords)! real ::rvals(nwords)!#endif real(DOUBLE_KIND) ::r8vals(nwords) pointer(ptr1, i2vals) pointer(ptr2, ivals) pointer(ptr3, rvals) pointer(ptr4, r8vals) if(mpp_io_stack_size< nwords) call mpp_io_set_stack_size(nwords) call mpp_error(FATAL, 'MPP_READ currently requires use_netCDF option') end subroutine READ_RECORD_CORE_ subroutine READ_RECORD_(unit, field, nwords, data, time_level, domain, position, tile_count, start_in, axsiz_in)!routine that is finally called by all mpp_read routines to perform the read!a non-netCDF record contains:! field ID! a set of 4 coordinates(is:ie, js:je) giving the data subdomain! a timelevel and a timestamp(=NULLTIME if field is static)! 3D real data(stored as 1D)!if you are using direct access I/O, the RECL argument to OPEN must be large enough for the above!in a global direct access file, record position on PE is given by %record.!Treatment of timestamp:! We assume that static fields have been passed without a timestamp.! Here that is converted into a timestamp of NULLTIME.! For non-netCDF fields, field is treated no differently, but is written! with a timestamp of NULLTIME. There is no check in the code to prevent! the user from repeatedly writing a static field. integer, intent(in) ::unit, nwords type(fieldtype), intent(in) ::field MPP_TYPE_, intent(inout) ::data(nwords) integer, intent(in), optional ::time_level type(domain2D), intent(in), optional ::domain integer, intent(in), optional ::position, tile_count integer, intent(in), optional ::start_in(:), axsiz_in(:) integer, dimension(size(field%axes(:))) ::start, axsiz integer ::tlevel !, subdomain(4) integer ::i, error, is, ie, js, je, isg, ieg, jsg, jeg type(domain2d), pointer ::io_domain=> tlevel if(PRESENT(start_in) .AND. PRESENT(axsiz_in)) then if(size(start(! the data domain and compute domain must refer to the subdomain being passed ! In this ! since that attempts to gather all data on PE size(field%axes(:)) axsiz(i)
subroutine drifters_core_print(self, ermesg)
subroutine, public drifters_core_del(self, ermesg)