19 #include "fms_switches.h"
20 #define _FLATTEN(A) reshape((A), (/size((A))/) )
70 #define _TYPE_DOMAIN2D integer
77 #define _MPP_PE mpp_pe()
78 #define _MPP_ROOT mpp_root_pe()
79 #define _MPP_NPES mpp_npes()
80 #define _TYPE_DOMAIN2D type(domain2d)
84 use drifters_core_mod,
only: drifters_core_type, drifters_core_new, drifters_core_del,
assignment(=)
86 use drifters_input_mod,
only: drifters_input_type, drifters_input_new, drifters_input_del,
assignment(=)
88 use drifters_io_mod,
only: drifters_io_type, drifters_io_new, drifters_io_del, drifters_io_set_time_units, &
89 drifters_io_set_position_names, drifters_io_set_position_units, &
90 drifters_io_set_field_names, drifters_io_set_field_units, drifters_io_write
92 use drifters_comm_mod,
only: drifters_comm_type,drifters_comm_new,drifters_comm_del, &
93 drifters_comm_set_pe_neighbors, drifters_comm_set_domain, &
94 drifters_comm_gather, drifters_comm_update
96 use cloud_interpolator_mod,
only: cld_ntrp_linear_cell_interp, cld_ntrp_locate_cell, cld_ntrp_get_cell_values
97 use platform_mod,
only: fms_path_len
101 public :: drifters_type,
assignment(=), drifters_push, drifters_compute_k, drifters_set_field
102 public :: drifters_new, drifters_del, drifters_set_domain, drifters_set_pe_neighbors
103 public :: drifters_set_v_axes, drifters_set_domain_bounds, drifters_positions2lonlat
104 public :: drifters_print_checksums, drifters_save, drifters_write_restart, drifters_distribute
106 integer,
parameter,
private :: MAX_STR_LEN = 128
108 #include<file_version.h>
116 type(drifters_core_type) :: core
117 type(drifters_input_type) :: input
118 type(drifters_io_type) :: io
119 type(drifters_comm_type) :: comm
123 real,
allocatable :: fields(:,:)
125 real,
allocatable :: xu(:)
126 real,
allocatable :: yu(:)
127 real,
allocatable :: zu(:)
128 real,
allocatable :: xv(:)
129 real,
allocatable :: yv(:)
130 real,
allocatable :: zv(:)
131 real,
allocatable :: xw(:)
132 real,
allocatable :: yw(:)
133 real,
allocatable :: zw(:)
135 real,
allocatable :: temp_pos(:,:)
137 real,
allocatable :: rk4_k1(:,:)
139 real,
allocatable :: rk4_k2(:,:)
141 real,
allocatable :: rk4_k3(:,:)
143 real,
allocatable :: rk4_k4(:,:)
146 character(len=FMS_PATH_LEN) :: input_file
147 character(len=FMS_PATH_LEN) :: output_file
150 logical :: rk4_completed
152 logical,
allocatable :: remove(:)
153 end type drifters_type
157 interface assignment(=)
158 module procedure drifters_copy_new
163 interface drifters_push
164 module procedure drifters_push_2
165 module procedure drifters_push_3
169 interface drifters_compute_k
170 module procedure drifters_computek2d
171 module procedure drifters_computek3d
176 interface drifters_set_field
177 module procedure drifters_set_field_2d
178 module procedure drifters_set_field_3d
190 subroutine drifters_new(self, input_file, output_file, ermesg)
192 type(drifters_type) :: self
193 character(len=*),
intent(in) :: input_file
194 character(len=*),
intent(in) :: output_file
196 character(len=*),
intent(out) :: ermesg
198 integer nd, nf, npdim, i
199 character(len=6) :: pe_str
203 self%input_file = input_file
204 self%output_file = output_file
206 call drifters_input_new(self%input, input_file, ermesg)
207 if(ermesg/=
'')
return
210 nd =
size(self%input%velocity_names)
212 npdim = int(1.3*
size(self%input%positions, 2))
213 call drifters_core_new(self%core, nd=nd, npdim=npdim, ermesg=ermesg)
214 if(ermesg/=
'')
return
217 nf =
size(self%input%field_names)
221 write(pe_str,
'(i6)') _mpp_pe
222 pe_str = adjustr(pe_str)
224 if(pe_str(i:i)==
' ') pe_str(i:i)=
'0'
226 call drifters_io_new(self%io, output_file//
'.'//pe_str, nd, nf, ermesg)
227 if(ermesg/=
'')
return
229 call drifters_comm_new(self%comm)
230 if(ermesg/=
'')
return
233 call drifters_io_set_time_units(self%io, name=self%input%time_units, &
236 call drifters_io_set_position_names(self%io, names=self%input%position_names, &
238 if(ermesg/=
'')
return
239 call drifters_io_set_position_units(self%io, names=self%input%position_units, &
241 if(ermesg/=
'')
return
243 call drifters_io_set_field_names(self%io, names=self%input%field_names, &
245 if(ermesg/=
'')
return
246 call drifters_io_set_field_units(self%io, names=self%input%field_units, &
248 if(ermesg/=
'')
return
255 self%rk4_completed = .false.
257 allocate(self%rk4_k1(self%core%nd, self%core%npdim))
258 self%rk4_k1 = -huge(1.)
259 allocate(self%rk4_k2(self%core%nd, self%core%npdim))
260 self%rk4_k2 = -huge(1.)
261 allocate(self%rk4_k3(self%core%nd, self%core%npdim))
262 self%rk4_k3 = -huge(1.)
263 allocate(self%rk4_k4(self%core%nd, self%core%npdim))
264 self%rk4_k4 = -huge(1.)
265 allocate(self%remove(self%core%npdim))
266 self%remove = .false.
267 allocate(self%temp_pos(nd, self%core%npdim))
268 self%temp_pos = -huge(1.)
270 allocate(self%fields(nf, self%core%npdim))
271 self%fields = -huge(1.)
273 end subroutine drifters_new
278 subroutine drifters_del(self, ermesg)
279 type(drifters_type) :: self
280 character(len=*),
intent(out) :: ermesg
284 deallocate(self%fields, stat=flag)
285 deallocate(self%xu, stat=flag)
286 deallocate(self%yu, stat=flag)
287 deallocate(self%zu, stat=flag)
288 deallocate(self%xv, stat=flag)
289 deallocate(self%yv, stat=flag)
290 deallocate(self%zv, stat=flag)
291 deallocate(self%xw, stat=flag)
292 deallocate(self%yw, stat=flag)
293 deallocate(self%zw, stat=flag)
294 deallocate(self%temp_pos, stat=flag)
295 deallocate(self%rk4_k1, stat=flag)
296 deallocate(self%rk4_k2, stat=flag)
297 deallocate(self%rk4_k3, stat=flag)
298 deallocate(self%rk4_k4, stat=flag)
299 deallocate(self%remove, stat=flag)
301 call drifters_core_del(self%core, ermesg)
302 if(ermesg/=
'')
return
303 call drifters_input_del(self%input, ermesg)
304 if(ermesg/=
'')
return
305 call drifters_io_del(self%io, ermesg)
306 if(ermesg/=
'')
return
307 call drifters_comm_del(self%comm)
308 if(ermesg/=
'')
return
310 end subroutine drifters_del
315 subroutine drifters_copy_new(new_instance, old_instance)
317 type(drifters_type),
intent(in) :: old_instance
318 type(drifters_type),
intent(inout) :: new_instance
320 character(len=MAX_STR_LEN) :: ermesg
325 call drifters_del(new_instance, ermesg)
326 if(ermesg/=
'')
return
328 new_instance%core = old_instance%core
329 new_instance%input = old_instance%input
330 new_instance%io = old_instance%io
331 new_instance%comm = old_instance%comm
333 new_instance%dt = old_instance%dt
334 new_instance%time = old_instance%time
336 allocate(new_instance%fields(
size(old_instance%fields, 1), &
337 &
size(old_instance%fields, 2) ))
338 new_instance%fields = old_instance%fields
340 allocate(new_instance%xu(
size(old_instance%xu) ))
341 allocate(new_instance%yu(
size(old_instance%yu) ))
342 allocate(new_instance%zu(
size(old_instance%zu) ))
343 new_instance%xu = old_instance%xu
344 new_instance%yu = old_instance%yu
345 new_instance%zu = old_instance%zu
346 allocate(new_instance%xv(
size(old_instance%xv) ))
347 allocate(new_instance%yv(
size(old_instance%yv) ))
348 allocate(new_instance%zv(
size(old_instance%zv) ))
349 new_instance%xv = old_instance%xv
350 new_instance%yv = old_instance%yv
351 new_instance%zv = old_instance%zv
352 allocate(new_instance%xw(
size(old_instance%xw) ))
353 allocate(new_instance%yw(
size(old_instance%yw) ))
354 allocate(new_instance%zw(
size(old_instance%zw) ))
355 new_instance%xw = old_instance%xw
356 new_instance%yw = old_instance%yw
357 new_instance%zw = old_instance%zw
359 allocate(new_instance%temp_pos(
size(old_instance%temp_pos,1), &
360 &
size(old_instance%temp_pos,2) ))
361 new_instance%temp_pos = old_instance%temp_pos
362 allocate(new_instance%rk4_k1(
size(old_instance%rk4_k1,1), &
363 &
size(old_instance%rk4_k1,2) ))
364 allocate(new_instance%rk4_k2(
size(old_instance%rk4_k2,1), &
365 &
size(old_instance%rk4_k2,2) ))
366 allocate(new_instance%rk4_k3(
size(old_instance%rk4_k3,1), &
367 &
size(old_instance%rk4_k3,2) ))
368 allocate(new_instance%rk4_k4(
size(old_instance%rk4_k4,1), &
369 &
size(old_instance%rk4_k4,2) ))
370 new_instance%rk4_k1 = old_instance%rk4_k1
371 new_instance%rk4_k2 = old_instance%rk4_k2
372 new_instance%rk4_k3 = old_instance%rk4_k3
373 new_instance%rk4_k4 = old_instance%rk4_k4
375 new_instance%rk4_step = old_instance%rk4_step
376 new_instance%rk4_completed = old_instance%rk4_completed
377 new_instance%nx = old_instance%nx
378 new_instance%ny = old_instance%ny
380 allocate(new_instance%remove(
size(old_instance%remove)))
381 new_instance%remove = old_instance%remove
384 end subroutine drifters_copy_new
401 subroutine drifters_set_domain(self, &
402 & xmin_comp, xmax_comp, ymin_comp, ymax_comp, &
403 & xmin_data, xmax_data, ymin_data, ymax_data, &
404 & xmin_glob, xmax_glob, ymin_glob, ymax_glob, &
406 type(drifters_type) :: self
408 real,
optional,
intent(in) :: xmin_comp
409 real,
optional,
intent(in) :: xmax_comp
410 real,
optional,
intent(in) :: ymin_comp
411 real,
optional,
intent(in) :: ymax_comp
413 real,
optional,
intent(in) :: xmin_data
414 real,
optional,
intent(in) :: xmax_data
415 real,
optional,
intent(in) :: ymin_data
416 real,
optional,
intent(in) :: ymax_data
418 real,
optional,
intent(in) :: xmin_glob
419 real,
optional,
intent(in) :: xmax_glob
420 real,
optional,
intent(in) :: ymin_glob
421 real,
optional,
intent(in) :: ymax_glob
422 character(len=*),
intent(out) :: ermesg
425 if(
present(xmin_comp)) self%comm%xcmin = xmin_comp
426 if(
present(xmax_comp)) self%comm%xcmax = xmax_comp
427 if(
present(ymin_comp)) self%comm%ycmin = ymin_comp
428 if(
present(ymax_comp)) self%comm%ycmax = ymax_comp
430 if(
present(xmin_data)) self%comm%xdmin = xmin_data
431 if(
present(xmax_data)) self%comm%xdmax = xmax_data
432 if(
present(ymin_data)) self%comm%ydmin = ymin_data
433 if(
present(ymax_data)) self%comm%ydmax = ymax_data
435 if(
present(xmin_glob)) self%comm%xgmin = xmin_glob
436 if(
present(xmax_glob)) self%comm%xgmax = xmax_glob
437 if(
present(ymin_glob)) self%comm%ygmin = ymin_glob
438 if(
present(ymax_glob)) self%comm%ygmax = ymax_glob
442 if(
present(xmin_glob) .and.
present(xmax_glob)) self%comm%xperiodic = .true.
443 if(
present(ymin_glob) .and.
present(ymax_glob)) self%comm%yperiodic = .true.
445 end subroutine drifters_set_domain
452 subroutine drifters_set_pe_neighbors(self, domain, ermesg)
454 type(drifters_type) :: self
455 _type_domain2d :: domain
456 character(len=*),
intent(out) :: ermesg
460 call drifters_comm_set_pe_neighbors(self%comm, domain)
462 end subroutine drifters_set_pe_neighbors
466 #define drifters_push_XXX drifters_push_2
467 #include "drifters_push.fh"
469 #undef drifters_push_XXX
473 #define drifters_push_XXX drifters_push_3
474 #include "drifters_push.fh"
476 #undef drifters_push_XXX
479 subroutine drifters_modulo(self, positions, ermesg)
480 type(drifters_type) :: self
481 real,
intent(inout) :: positions(:,:)
482 character(len=*),
intent(out) :: ermesg
490 if(self%comm%xperiodic)
then
493 positions(1, ip) = self%comm%xgmin + &
494 & modulo(x - self%comm%xgmin, self%comm%xgmax-self%comm%xgmin)
498 if(self%comm%yperiodic)
then
501 positions(2, ip) = self%comm%ygmin + &
502 & modulo(y - self%comm%ygmin, self%comm%ygmax-self%comm%ygmin)
506 end subroutine drifters_modulo
510 #define drifters_set_field_XXX drifters_set_field_2d
511 #include "drifters_set_field.fh"
513 #undef drifters_set_field_XXX
517 #define drifters_set_field_XXX drifters_set_field_3d
518 #include "drifters_set_field.fh"
520 #undef drifters_set_field_XXX
526 subroutine drifters_save(self, ermesg)
527 type(drifters_type) :: self
528 character(len=*),
intent(out) :: ermesg
533 nf =
size(self%input%field_names)
537 call drifters_io_write(self%io, self%time, np, self%core%nd, nf, &
538 & self%core%ids, self%core%positions, &
539 & fields=self%fields(:,1:np), ermesg=ermesg)
541 end subroutine drifters_save
548 subroutine drifters_distribute(self, ermesg)
549 type(drifters_type) :: self
550 character(len=*),
intent(out) :: ermesg
558 ermesg =
'drifters_distribute: dimension must be >=2'
562 nptot =
size(self%input%positions, 2)
564 x = self%input%positions(1,i)
565 y = self%input%positions(2,i)
566 if(x >= self%comm%xdmin .and. x <= self%comm%xdmax .and. &
567 & y >= self%comm%ydmin .and. y <= self%comm%ydmax)
then
569 self%core%np = self%core%np + 1
570 self%core%positions(1:nd, self%core%np) = self%input%positions(1:nd, i)
571 self%core%ids(self%core%np) = i
576 end subroutine drifters_distribute
583 subroutine drifters_write_restart(self, filename, &
586 & root, mycomm, ermesg)
590 type(drifters_type) :: self
591 character(len=*),
intent(in) :: filename
595 real,
intent(in),
optional :: x1(:)
596 real,
intent(in),
optional :: y1(:)
597 real,
intent(in),
optional :: geolon1(:,:)
598 real,
intent(in),
optional :: x2(:)
599 real,
intent(in),
optional :: y2(:)
600 real,
intent(in),
optional :: geolat2(:,:)
603 integer,
intent(in),
optional :: root
604 integer,
intent(in),
optional :: mycomm
605 character(len=*),
intent(out) :: ermesg
608 logical :: do_save_lonlat
609 real,
allocatable :: lons(:), lats(:)
615 allocate(lons(np), lats(np))
620 if(
present(x1) .and.
present(y1) .and.
present(geolon1) .and. &
621 &
present(x2) .and.
present(y2) .and.
present(geolat2))
then
622 do_save_lonlat = .true.
624 do_save_lonlat = .false.
627 if(do_save_lonlat)
then
630 call drifters_positions2lonlat(self, &
631 & positions=self%core%positions(:,1:np), &
632 & x1=x1, y1=y1, geolon1=geolon1, &
633 & x2=x2, y2=y2, geolat2=geolat2, &
634 & lons=lons, lats=lats, ermesg=ermesg)
635 if(ermesg/=
'')
return
639 call drifters_comm_gather(self%comm, self%core, self%input, &
640 & lons, lats, do_save_lonlat, &
644 end subroutine drifters_write_restart
648 #define drifters_compute_k_XXX drifters_computek2d
649 #include "drifters_compute_k.fh"
651 #undef drifters_compute_k_XXX
655 #define drifters_compute_k_XXX drifters_computek3d
656 #include "drifters_compute_k.fh"
658 #undef drifters_compute_k_XXX
667 subroutine drifters_set_v_axes(self, component, x, y, z, ermesg)
668 type(drifters_type) :: self
669 character(len=*),
intent(in) :: component
670 real,
intent(in) :: x(:)
671 real,
intent(in) :: y(:)
672 real,
intent(in) :: z(:)
673 character(len=*),
intent(out) :: ermesg
675 integer ier, nx, ny, nz
681 select case (component(1:1))
684 deallocate(self%xu, stat=ier)
685 allocate(self%xu(nx))
687 self%nx = max(self%nx,
size(x))
690 deallocate(self%yu, stat=ier)
691 allocate(self%yu(ny))
693 self%ny = max(self%ny,
size(y))
696 deallocate(self%zu, stat=ier)
697 allocate(self%zu(nz))
702 deallocate(self%xv, stat=ier)
703 allocate(self%xv(nx))
705 self%nx = max(self%nx,
size(x))
708 deallocate(self%yv, stat=ier)
709 allocate(self%yv(ny))
711 self%ny = max(self%ny,
size(y))
714 deallocate(self%zv, stat=ier)
715 allocate(self%zv(nz))
720 deallocate(self%xw, stat=ier)
721 allocate(self%xw(nx))
723 self%nx = max(self%nx,
size(x))
726 deallocate(self%yw, stat=ier)
727 allocate(self%yw(ny))
729 self%ny = max(self%ny,
size(y))
732 deallocate(self%zw, stat=ier)
733 allocate(self%zw(nz))
737 ermesg =
'drifters_set_v_axes: ERROR component must be "u", "v" or "w"'
739 end subroutine drifters_set_v_axes
744 subroutine drifters_set_domain_bounds(self, domain, backoff_x, backoff_y, ermesg)
745 type(drifters_type) :: self
746 _type_domain2d :: domain
747 integer,
intent(in) :: backoff_x
748 integer,
intent(in) :: backoff_y
749 character(len=*),
intent(out) :: ermesg
753 if(.not.
allocated(self%xu) .or. .not.
allocated(self%yu))
then
754 ermesg =
'drifters_set_domain_bounds: ERROR "u"-component axes not set'
757 call drifters_comm_set_domain(self%comm, domain, self%xu, self%yu, backoff_x, backoff_y)
758 if(.not.
allocated(self%xv) .or. .not.
allocated(self%yv))
then
759 ermesg =
'drifters_set_domain_bounds: ERROR "v"-component axes not set'
762 if(
allocated(self%xw) .and.
allocated(self%yw))
then
763 call drifters_comm_set_domain(self%comm, domain, self%xv, self%yv, backoff_x, backoff_y)
767 end subroutine drifters_set_domain_bounds
773 subroutine drifters_positions2lonlat(self, positions, &
779 type(drifters_type) :: self
781 real,
intent(in) :: positions(:,:)
783 real,
intent(in) :: x1(:)
784 real,
intent(in) :: y1(:)
785 real,
intent(in) :: geolon1(:,:)
786 real,
intent(in) :: x2(:)
787 real,
intent(in) :: y2(:)
788 real,
intent(in) :: geolat2(:,:)
790 real,
intent(out) :: lons(:)
791 real,
intent(out) :: lats(:)
792 character(len=*),
intent(out) :: ermesg
794 real fvals(2**self%core%nd), ts(self%core%nd)
795 integer np, ij(2), ip, ier, n1s(2), n2s(2), i, j, iertot
796 character(len=10) :: n1_str, n2_str, np_str, iertot_str
803 n1s = (/
size(x1),
size(y1)/)
804 n2s = (/
size(x2),
size(y2)/)
805 if(n1s(1) /=
size(geolon1, 1) .or. n1s(2) /=
size(geolon1, 2))
then
806 ermesg =
'drifters_positions2geolonlat: ERROR incompatibles dims between (x1, y1, geolon1)'
809 if(n2s(1) /=
size(geolat2, 1) .or. n2s(2) /=
size(geolat2, 2))
then
810 ermesg =
'drifters_positions2geolonlat: ERROR incompatibles dims between (x2, y2, geolat2)'
814 np =
size(positions, 2)
815 if(
size(lons) < np .or.
size(lats) < np)
then
816 write(np_str,
'(i10)') np
817 write(n1_str,
'(i10)')
size(lons)
818 write(n2_str,
'(i10)')
size(lats)
819 ermesg =
'drifters_positions2geolonlat: ERROR size of "lons" ('//trim(n1_str)// &
820 &
') or "lats" ('//trim(n2_str)//
') < '//trim(np_str)
829 call cld_ntrp_locate_cell(x1, positions(1,ip), i, ier)
830 iertot = iertot + ier
831 call cld_ntrp_locate_cell(y1, positions(2,ip), j, ier)
832 iertot = iertot + ier
833 ij(1) = i; ij(2) = j;
834 call cld_ntrp_get_cell_values(n1s, _flatten(geolon1), ij, fvals, ier)
835 iertot = iertot + ier
836 ts(1) = (positions(1,ip) - x1(i))/(x1(i+1) - x1(i))
837 ts(2) = (positions(2,ip) - y1(j))/(y1(j+1) - y1(j))
838 call cld_ntrp_linear_cell_interp(fvals, ts, lons(ip), ier)
839 iertot = iertot + ier
842 call cld_ntrp_locate_cell(x2, positions(1,ip), i, ier)
843 iertot = iertot + ier
844 call cld_ntrp_locate_cell(y2, positions(2,ip), j, ier)
845 iertot = iertot + ier
846 ij(1) = i; ij(2) = j;
847 call cld_ntrp_get_cell_values(n2s, _flatten(geolat2), ij, fvals, ier)
848 iertot = iertot + ier
849 ts(1) = (positions(1,ip) - x2(i))/(x2(i+1) - x2(i))
850 ts(2) = (positions(2,ip) - y2(j))/(y2(j+1) - y2(j))
851 call cld_ntrp_linear_cell_interp(fvals, ts, lats(ip), ier)
852 iertot = iertot + ier
857 write(iertot_str,
'(i10)') iertot
858 ermesg =
'drifters_positions2geolonlat: ERROR '//trim(iertot_str)// &
859 &
' interpolation errors (domain out of bounds?)'
862 end subroutine drifters_positions2lonlat
866 subroutine drifters_print_checksums(self, pe, ermesg)
868 type(drifters_type) :: self
869 integer,
intent(in),
optional :: pe
870 character(len=*),
intent(out) :: ermesg
872 integer,
parameter :: i8 = selected_int_kind(13)
873 integer(i8) :: mold, chksum_pos, chksum_k1, chksum_k2, chksum_k3, chksum_k4
874 integer(i8) :: chksum_tot
879 if(.not.
present(pe))
then
885 if(me == _mpp_pe)
then
889 chksum_pos = transfer(sum(sum(self%core%positions(1:nd,1:np),1)), mold)
890 chksum_k1 = transfer(sum(sum(self%rk4_k1(1:nd,1:np),1)), mold)
891 chksum_k2 = transfer(sum(sum(self%rk4_k2(1:nd,1:np),1)), mold)
892 chksum_k3 = transfer(sum(sum(self%rk4_k3(1:nd,1:np),1)), mold)
893 chksum_k4 = transfer(sum(sum(self%rk4_k4(1:nd,1:np),1)), mold)
894 chksum_tot = chksum_pos + chksum_k1 + chksum_k2 + chksum_k3 +chksum_k4
896 print *,
'==============drifters checksums=========================='
897 print
'(a,i25,a,i6,a,e15.7)',
'==positions: ', chksum_pos,
' PE=', me,
' time = ', self%time
898 print
'(a,i25,a,i6,a,e15.7)',
'==k1 : ', chksum_k1,
' PE=', me,
' time = ', self%time
899 print
'(a,i25,a,i6,a,e15.7)',
'==k2 : ', chksum_k2,
' PE=', me,
' time = ', self%time
900 print
'(a,i25,a,i6,a,e15.7)',
'==k3 : ', chksum_k3,
' PE=', me,
' time = ', self%time
901 print
'(a,i25,a,i6,a,e15.7)',
'==k4 : ', chksum_k4,
' PE=', me,
' time = ', self%time
902 print
'(a,i25,a,i6,a,e15.7)',
'==total : ', chksum_tot,
' PE=', me,
' time = ', self%time
906 end subroutine drifters_print_checksums
908 subroutine drifters_reset_rk4(self, ermesg)
909 type(drifters_type) :: self
910 character(len=*),
intent(out) :: ermesg
916 if(
size(self%rk4_k1, 2) < self%core%np)
then
917 deallocate(self%rk4_k1, stat=ier)
918 allocate(self%rk4_k1(self%core%nd, self%core%npdim))
921 if(
size(self%rk4_k2, 2) < self%core%np)
then
922 deallocate(self%rk4_k2, stat=ier)
923 allocate(self%rk4_k2(self%core%nd, self%core%npdim))
926 if(
size(self%rk4_k3, 2) < self%core%np)
then
927 deallocate(self%rk4_k3, stat=ier)
928 allocate(self%rk4_k3(self%core%nd, self%core%npdim))
931 if(
size(self%rk4_k4, 2) < self%core%np)
then
932 deallocate(self%rk4_k4, stat=ier)
933 allocate(self%rk4_k4(self%core%nd, self%core%npdim))
937 if(
size(self%remove) < self%core%np)
then
938 deallocate(self%remove, stat=ier)
939 allocate(self%remove(self%core%npdim))
940 self%remove = .false.
943 if(
size(self%temp_pos, 2) < self%core%np)
then
944 deallocate(self%temp_pos, stat=ier)
945 nd =
size(self%input%velocity_names)
946 allocate(self%temp_pos(nd, self%core%npdim))
947 self%temp_pos = -huge(1.)
950 end subroutine drifters_reset_rk4
952 end module drifters_mod
The domain2D type contains all the necessary information to define the global, compute and data domai...
integer function mpp_npes()
Returns processor count for current pelist.
integer function mpp_pe()
Returns processor ID.