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)