20 #include "fms_switches.h"
21 #define _FLATTEN(A) reshape((A), (/size((A))/) )
71 #define _TYPE_DOMAIN2D integer
78 #define _MPP_PE mpp_pe()
79 #define _MPP_ROOT mpp_root_pe()
80 #define _MPP_NPES mpp_npes()
81 #define _TYPE_DOMAIN2D type(domain2d)
85 use drifters_core_mod,
only: drifters_core_type, drifters_core_new, drifters_core_del,
assignment(=)
87 use drifters_input_mod,
only: drifters_input_type, drifters_input_new, drifters_input_del,
assignment(=)
89 use drifters_io_mod,
only: drifters_io_type, drifters_io_new, drifters_io_del, drifters_io_set_time_units, &
90 drifters_io_set_position_names, drifters_io_set_position_units, &
91 drifters_io_set_field_names, drifters_io_set_field_units, drifters_io_write
93 use drifters_comm_mod,
only: drifters_comm_type,drifters_comm_new,drifters_comm_del, &
94 drifters_comm_set_pe_neighbors, drifters_comm_set_domain, &
95 drifters_comm_gather, drifters_comm_update
97 use cloud_interpolator_mod,
only: cld_ntrp_linear_cell_interp, cld_ntrp_locate_cell, cld_ntrp_get_cell_values
98 use platform_mod,
only: fms_path_len
102 public :: drifters_type,
assignment(=), drifters_push, drifters_compute_k, drifters_set_field
103 public :: drifters_new, drifters_del, drifters_set_domain, drifters_set_pe_neighbors
104 public :: drifters_set_v_axes, drifters_set_domain_bounds, drifters_positions2lonlat
105 public :: drifters_print_checksums, drifters_save, drifters_write_restart, drifters_distribute
107 integer,
parameter,
private :: MAX_STR_LEN = 128
109 #include<file_version.h>
117 type(drifters_core_type) :: core
118 type(drifters_input_type) :: input
119 type(drifters_io_type) :: io
120 type(drifters_comm_type) :: comm
124 real,
allocatable :: fields(:,:)
126 real,
allocatable :: xu(:)
127 real,
allocatable :: yu(:)
128 real,
allocatable :: zu(:)
129 real,
allocatable :: xv(:)
130 real,
allocatable :: yv(:)
131 real,
allocatable :: zv(:)
132 real,
allocatable :: xw(:)
133 real,
allocatable :: yw(:)
134 real,
allocatable :: zw(:)
136 real,
allocatable :: temp_pos(:,:)
138 real,
allocatable :: rk4_k1(:,:)
140 real,
allocatable :: rk4_k2(:,:)
142 real,
allocatable :: rk4_k3(:,:)
144 real,
allocatable :: rk4_k4(:,:)
147 character(len=FMS_PATH_LEN) :: input_file
148 character(len=FMS_PATH_LEN) :: output_file
151 logical :: rk4_completed
153 logical,
allocatable :: remove(:)
154 end type drifters_type
158 interface assignment(=)
159 module procedure drifters_copy_new
164 interface drifters_push
165 module procedure drifters_push_2
166 module procedure drifters_push_3
170 interface drifters_compute_k
171 module procedure drifters_computek2d
172 module procedure drifters_computek3d
177 interface drifters_set_field
178 module procedure drifters_set_field_2d
179 module procedure drifters_set_field_3d
191 subroutine drifters_new(self, input_file, output_file, ermesg)
193 type(drifters_type) :: self
194 character(len=*),
intent(in) :: input_file
195 character(len=*),
intent(in) :: output_file
197 character(len=*),
intent(out) :: ermesg
199 integer nd, nf, npdim, i
200 character(len=6) :: pe_str
204 self%input_file = input_file
205 self%output_file = output_file
207 call drifters_input_new(self%input, input_file, ermesg)
208 if(ermesg/=
'')
return
211 nd =
size(self%input%velocity_names)
213 npdim = int(1.3*
size(self%input%positions, 2))
214 call drifters_core_new(self%core, nd=nd, npdim=npdim, ermesg=ermesg)
215 if(ermesg/=
'')
return
218 nf =
size(self%input%field_names)
222 write(pe_str,
'(i6)') _mpp_pe
223 pe_str = adjustr(pe_str)
225 if(pe_str(i:i)==
' ') pe_str(i:i)=
'0'
227 call drifters_io_new(self%io, output_file//
'.'//pe_str, nd, nf, ermesg)
228 if(ermesg/=
'')
return
230 call drifters_comm_new(self%comm)
231 if(ermesg/=
'')
return
234 call drifters_io_set_time_units(self%io, name=self%input%time_units, &
237 call drifters_io_set_position_names(self%io, names=self%input%position_names, &
239 if(ermesg/=
'')
return
240 call drifters_io_set_position_units(self%io, names=self%input%position_units, &
242 if(ermesg/=
'')
return
244 call drifters_io_set_field_names(self%io, names=self%input%field_names, &
246 if(ermesg/=
'')
return
247 call drifters_io_set_field_units(self%io, names=self%input%field_units, &
249 if(ermesg/=
'')
return
256 self%rk4_completed = .false.
258 allocate(self%rk4_k1(self%core%nd, self%core%npdim))
259 self%rk4_k1 = -huge(1.)
260 allocate(self%rk4_k2(self%core%nd, self%core%npdim))
261 self%rk4_k2 = -huge(1.)
262 allocate(self%rk4_k3(self%core%nd, self%core%npdim))
263 self%rk4_k3 = -huge(1.)
264 allocate(self%rk4_k4(self%core%nd, self%core%npdim))
265 self%rk4_k4 = -huge(1.)
266 allocate(self%remove(self%core%npdim))
267 self%remove = .false.
268 allocate(self%temp_pos(nd, self%core%npdim))
269 self%temp_pos = -huge(1.)
271 allocate(self%fields(nf, self%core%npdim))
272 self%fields = -huge(1.)
274 end subroutine drifters_new
279 subroutine drifters_del(self, ermesg)
280 type(drifters_type) :: self
281 character(len=*),
intent(out) :: ermesg
285 deallocate(self%fields, stat=flag)
286 deallocate(self%xu, stat=flag)
287 deallocate(self%yu, stat=flag)
288 deallocate(self%zu, stat=flag)
289 deallocate(self%xv, stat=flag)
290 deallocate(self%yv, stat=flag)
291 deallocate(self%zv, stat=flag)
292 deallocate(self%xw, stat=flag)
293 deallocate(self%yw, stat=flag)
294 deallocate(self%zw, stat=flag)
295 deallocate(self%temp_pos, stat=flag)
296 deallocate(self%rk4_k1, stat=flag)
297 deallocate(self%rk4_k2, stat=flag)
298 deallocate(self%rk4_k3, stat=flag)
299 deallocate(self%rk4_k4, stat=flag)
300 deallocate(self%remove, stat=flag)
302 call drifters_core_del(self%core, ermesg)
303 if(ermesg/=
'')
return
304 call drifters_input_del(self%input, ermesg)
305 if(ermesg/=
'')
return
306 call drifters_io_del(self%io, ermesg)
307 if(ermesg/=
'')
return
308 call drifters_comm_del(self%comm)
309 if(ermesg/=
'')
return
311 end subroutine drifters_del
316 subroutine drifters_copy_new(new_instance, old_instance)
318 type(drifters_type),
intent(in) :: old_instance
319 type(drifters_type),
intent(inout) :: new_instance
321 character(len=MAX_STR_LEN) :: ermesg
326 call drifters_del(new_instance, ermesg)
327 if(ermesg/=
'')
return
329 new_instance%core = old_instance%core
330 new_instance%input = old_instance%input
331 new_instance%io = old_instance%io
332 new_instance%comm = old_instance%comm
334 new_instance%dt = old_instance%dt
335 new_instance%time = old_instance%time
337 allocate(new_instance%fields(
size(old_instance%fields, 1), &
338 &
size(old_instance%fields, 2) ))
339 new_instance%fields = old_instance%fields
341 allocate(new_instance%xu(
size(old_instance%xu) ))
342 allocate(new_instance%yu(
size(old_instance%yu) ))
343 allocate(new_instance%zu(
size(old_instance%zu) ))
344 new_instance%xu = old_instance%xu
345 new_instance%yu = old_instance%yu
346 new_instance%zu = old_instance%zu
347 allocate(new_instance%xv(
size(old_instance%xv) ))
348 allocate(new_instance%yv(
size(old_instance%yv) ))
349 allocate(new_instance%zv(
size(old_instance%zv) ))
350 new_instance%xv = old_instance%xv
351 new_instance%yv = old_instance%yv
352 new_instance%zv = old_instance%zv
353 allocate(new_instance%xw(
size(old_instance%xw) ))
354 allocate(new_instance%yw(
size(old_instance%yw) ))
355 allocate(new_instance%zw(
size(old_instance%zw) ))
356 new_instance%xw = old_instance%xw
357 new_instance%yw = old_instance%yw
358 new_instance%zw = old_instance%zw
360 allocate(new_instance%temp_pos(
size(old_instance%temp_pos,1), &
361 &
size(old_instance%temp_pos,2) ))
362 new_instance%temp_pos = old_instance%temp_pos
363 allocate(new_instance%rk4_k1(
size(old_instance%rk4_k1,1), &
364 &
size(old_instance%rk4_k1,2) ))
365 allocate(new_instance%rk4_k2(
size(old_instance%rk4_k2,1), &
366 &
size(old_instance%rk4_k2,2) ))
367 allocate(new_instance%rk4_k3(
size(old_instance%rk4_k3,1), &
368 &
size(old_instance%rk4_k3,2) ))
369 allocate(new_instance%rk4_k4(
size(old_instance%rk4_k4,1), &
370 &
size(old_instance%rk4_k4,2) ))
371 new_instance%rk4_k1 = old_instance%rk4_k1
372 new_instance%rk4_k2 = old_instance%rk4_k2
373 new_instance%rk4_k3 = old_instance%rk4_k3
374 new_instance%rk4_k4 = old_instance%rk4_k4
376 new_instance%rk4_step = old_instance%rk4_step
377 new_instance%rk4_completed = old_instance%rk4_completed
378 new_instance%nx = old_instance%nx
379 new_instance%ny = old_instance%ny
381 allocate(new_instance%remove(
size(old_instance%remove)))
382 new_instance%remove = old_instance%remove
385 end subroutine drifters_copy_new
402 subroutine drifters_set_domain(self, &
403 & xmin_comp, xmax_comp, ymin_comp, ymax_comp, &
404 & xmin_data, xmax_data, ymin_data, ymax_data, &
405 & xmin_glob, xmax_glob, ymin_glob, ymax_glob, &
407 type(drifters_type) :: self
409 real,
optional,
intent(in) :: xmin_comp
410 real,
optional,
intent(in) :: xmax_comp
411 real,
optional,
intent(in) :: ymin_comp
412 real,
optional,
intent(in) :: ymax_comp
414 real,
optional,
intent(in) :: xmin_data
415 real,
optional,
intent(in) :: xmax_data
416 real,
optional,
intent(in) :: ymin_data
417 real,
optional,
intent(in) :: ymax_data
419 real,
optional,
intent(in) :: xmin_glob
420 real,
optional,
intent(in) :: xmax_glob
421 real,
optional,
intent(in) :: ymin_glob
422 real,
optional,
intent(in) :: ymax_glob
423 character(len=*),
intent(out) :: ermesg
426 if(
present(xmin_comp)) self%comm%xcmin = xmin_comp
427 if(
present(xmax_comp)) self%comm%xcmax = xmax_comp
428 if(
present(ymin_comp)) self%comm%ycmin = ymin_comp
429 if(
present(ymax_comp)) self%comm%ycmax = ymax_comp
431 if(
present(xmin_data)) self%comm%xdmin = xmin_data
432 if(
present(xmax_data)) self%comm%xdmax = xmax_data
433 if(
present(ymin_data)) self%comm%ydmin = ymin_data
434 if(
present(ymax_data)) self%comm%ydmax = ymax_data
436 if(
present(xmin_glob)) self%comm%xgmin = xmin_glob
437 if(
present(xmax_glob)) self%comm%xgmax = xmax_glob
438 if(
present(ymin_glob)) self%comm%ygmin = ymin_glob
439 if(
present(ymax_glob)) self%comm%ygmax = ymax_glob
443 if(
present(xmin_glob) .and.
present(xmax_glob)) self%comm%xperiodic = .true.
444 if(
present(ymin_glob) .and.
present(ymax_glob)) self%comm%yperiodic = .true.
446 end subroutine drifters_set_domain
453 subroutine drifters_set_pe_neighbors(self, domain, ermesg)
455 type(drifters_type) :: self
456 _type_domain2d :: domain
457 character(len=*),
intent(out) :: ermesg
461 call drifters_comm_set_pe_neighbors(self%comm, domain)
463 end subroutine drifters_set_pe_neighbors
467 #define drifters_push_XXX drifters_push_2
468 #include "drifters_push.fh"
470 #undef drifters_push_XXX
474 #define drifters_push_XXX drifters_push_3
475 #include "drifters_push.fh"
477 #undef drifters_push_XXX
480 subroutine drifters_modulo(self, positions, ermesg)
481 type(drifters_type) :: self
482 real,
intent(inout) :: positions(:,:)
483 character(len=*),
intent(out) :: ermesg
491 if(self%comm%xperiodic)
then
494 positions(1, ip) = self%comm%xgmin + &
495 & modulo(x - self%comm%xgmin, self%comm%xgmax-self%comm%xgmin)
499 if(self%comm%yperiodic)
then
502 positions(2, ip) = self%comm%ygmin + &
503 & modulo(y - self%comm%ygmin, self%comm%ygmax-self%comm%ygmin)
507 end subroutine drifters_modulo
511 #define drifters_set_field_XXX drifters_set_field_2d
512 #include "drifters_set_field.fh"
514 #undef drifters_set_field_XXX
518 #define drifters_set_field_XXX drifters_set_field_3d
519 #include "drifters_set_field.fh"
521 #undef drifters_set_field_XXX
527 subroutine drifters_save(self, ermesg)
528 type(drifters_type) :: self
529 character(len=*),
intent(out) :: ermesg
534 nf =
size(self%input%field_names)
538 call drifters_io_write(self%io, self%time, np, self%core%nd, nf, &
539 & self%core%ids, self%core%positions, &
540 & fields=self%fields(:,1:np), ermesg=ermesg)
542 end subroutine drifters_save
549 subroutine drifters_distribute(self, ermesg)
550 type(drifters_type) :: self
551 character(len=*),
intent(out) :: ermesg
559 ermesg =
'drifters_distribute: dimension must be >=2'
563 nptot =
size(self%input%positions, 2)
565 x = self%input%positions(1,i)
566 y = self%input%positions(2,i)
567 if(x >= self%comm%xdmin .and. x <= self%comm%xdmax .and. &
568 & y >= self%comm%ydmin .and. y <= self%comm%ydmax)
then
570 self%core%np = self%core%np + 1
571 self%core%positions(1:nd, self%core%np) = self%input%positions(1:nd, i)
572 self%core%ids(self%core%np) = i
577 end subroutine drifters_distribute
584 subroutine drifters_write_restart(self, filename, &
587 & root, mycomm, ermesg)
591 type(drifters_type) :: self
592 character(len=*),
intent(in) :: filename
596 real,
intent(in),
optional :: x1(:)
597 real,
intent(in),
optional :: y1(:)
598 real,
intent(in),
optional :: geolon1(:,:)
599 real,
intent(in),
optional :: x2(:)
600 real,
intent(in),
optional :: y2(:)
601 real,
intent(in),
optional :: geolat2(:,:)
604 integer,
intent(in),
optional :: root
605 integer,
intent(in),
optional :: mycomm
606 character(len=*),
intent(out) :: ermesg
609 logical :: do_save_lonlat
610 real,
allocatable :: lons(:), lats(:)
616 allocate(lons(np), lats(np))
621 if(
present(x1) .and.
present(y1) .and.
present(geolon1) .and. &
622 &
present(x2) .and.
present(y2) .and.
present(geolat2))
then
623 do_save_lonlat = .true.
625 do_save_lonlat = .false.
628 if(do_save_lonlat)
then
631 call drifters_positions2lonlat(self, &
632 & positions=self%core%positions(:,1:np), &
633 & x1=x1, y1=y1, geolon1=geolon1, &
634 & x2=x2, y2=y2, geolat2=geolat2, &
635 & lons=lons, lats=lats, ermesg=ermesg)
636 if(ermesg/=
'')
return
640 call drifters_comm_gather(self%comm, self%core, self%input, &
641 & lons, lats, do_save_lonlat, &
645 end subroutine drifters_write_restart
649 #define drifters_compute_k_XXX drifters_computek2d
650 #include "drifters_compute_k.fh"
652 #undef drifters_compute_k_XXX
656 #define drifters_compute_k_XXX drifters_computek3d
657 #include "drifters_compute_k.fh"
659 #undef drifters_compute_k_XXX
668 subroutine drifters_set_v_axes(self, component, x, y, z, ermesg)
669 type(drifters_type) :: self
670 character(len=*),
intent(in) :: component
671 real,
intent(in) :: x(:)
672 real,
intent(in) :: y(:)
673 real,
intent(in) :: z(:)
674 character(len=*),
intent(out) :: ermesg
676 integer ier, nx, ny, nz
682 select case (component(1:1))
685 deallocate(self%xu, stat=ier)
686 allocate(self%xu(nx))
688 self%nx = max(self%nx,
size(x))
691 deallocate(self%yu, stat=ier)
692 allocate(self%yu(ny))
694 self%ny = max(self%ny,
size(y))
697 deallocate(self%zu, stat=ier)
698 allocate(self%zu(nz))
703 deallocate(self%xv, stat=ier)
704 allocate(self%xv(nx))
706 self%nx = max(self%nx,
size(x))
709 deallocate(self%yv, stat=ier)
710 allocate(self%yv(ny))
712 self%ny = max(self%ny,
size(y))
715 deallocate(self%zv, stat=ier)
716 allocate(self%zv(nz))
721 deallocate(self%xw, stat=ier)
722 allocate(self%xw(nx))
724 self%nx = max(self%nx,
size(x))
727 deallocate(self%yw, stat=ier)
728 allocate(self%yw(ny))
730 self%ny = max(self%ny,
size(y))
733 deallocate(self%zw, stat=ier)
734 allocate(self%zw(nz))
738 ermesg =
'drifters_set_v_axes: ERROR component must be "u", "v" or "w"'
740 end subroutine drifters_set_v_axes
745 subroutine drifters_set_domain_bounds(self, domain, backoff_x, backoff_y, ermesg)
746 type(drifters_type) :: self
747 _type_domain2d :: domain
748 integer,
intent(in) :: backoff_x
749 integer,
intent(in) :: backoff_y
750 character(len=*),
intent(out) :: ermesg
754 if(.not.
allocated(self%xu) .or. .not.
allocated(self%yu))
then
755 ermesg =
'drifters_set_domain_bounds: ERROR "u"-component axes not set'
758 call drifters_comm_set_domain(self%comm, domain, self%xu, self%yu, backoff_x, backoff_y)
759 if(.not.
allocated(self%xv) .or. .not.
allocated(self%yv))
then
760 ermesg =
'drifters_set_domain_bounds: ERROR "v"-component axes not set'
763 if(
allocated(self%xw) .and.
allocated(self%yw))
then
764 call drifters_comm_set_domain(self%comm, domain, self%xv, self%yv, backoff_x, backoff_y)
768 end subroutine drifters_set_domain_bounds
774 subroutine drifters_positions2lonlat(self, positions, &
780 type(drifters_type) :: self
782 real,
intent(in) :: positions(:,:)
784 real,
intent(in) :: x1(:)
785 real,
intent(in) :: y1(:)
786 real,
intent(in) :: geolon1(:,:)
787 real,
intent(in) :: x2(:)
788 real,
intent(in) :: y2(:)
789 real,
intent(in) :: geolat2(:,:)
791 real,
intent(out) :: lons(:)
792 real,
intent(out) :: lats(:)
793 character(len=*),
intent(out) :: ermesg
795 real fvals(2**self%core%nd), ts(self%core%nd)
796 integer np, ij(2), ip, ier, n1s(2), n2s(2), i, j, iertot
797 character(len=10) :: n1_str, n2_str, np_str, iertot_str
804 n1s = (/
size(x1),
size(y1)/)
805 n2s = (/
size(x2),
size(y2)/)
806 if(n1s(1) /=
size(geolon1, 1) .or. n1s(2) /=
size(geolon1, 2))
then
807 ermesg =
'drifters_positions2geolonlat: ERROR incompatibles dims between (x1, y1, geolon1)'
810 if(n2s(1) /=
size(geolat2, 1) .or. n2s(2) /=
size(geolat2, 2))
then
811 ermesg =
'drifters_positions2geolonlat: ERROR incompatibles dims between (x2, y2, geolat2)'
815 np =
size(positions, 2)
816 if(
size(lons) < np .or.
size(lats) < np)
then
817 write(np_str,
'(i10)') np
818 write(n1_str,
'(i10)')
size(lons)
819 write(n2_str,
'(i10)')
size(lats)
820 ermesg =
'drifters_positions2geolonlat: ERROR size of "lons" ('//trim(n1_str)// &
821 &
') or "lats" ('//trim(n2_str)//
') < '//trim(np_str)
830 call cld_ntrp_locate_cell(x1, positions(1,ip), i, ier)
831 iertot = iertot + ier
832 call cld_ntrp_locate_cell(y1, positions(2,ip), j, ier)
833 iertot = iertot + ier
834 ij(1) = i; ij(2) = j;
835 call cld_ntrp_get_cell_values(n1s, _flatten(geolon1), ij, fvals, ier)
836 iertot = iertot + ier
837 ts(1) = (positions(1,ip) - x1(i))/(x1(i+1) - x1(i))
838 ts(2) = (positions(2,ip) - y1(j))/(y1(j+1) - y1(j))
839 call cld_ntrp_linear_cell_interp(fvals, ts, lons(ip), ier)
840 iertot = iertot + ier
843 call cld_ntrp_locate_cell(x2, positions(1,ip), i, ier)
844 iertot = iertot + ier
845 call cld_ntrp_locate_cell(y2, positions(2,ip), j, ier)
846 iertot = iertot + ier
847 ij(1) = i; ij(2) = j;
848 call cld_ntrp_get_cell_values(n2s, _flatten(geolat2), ij, fvals, ier)
849 iertot = iertot + ier
850 ts(1) = (positions(1,ip) - x2(i))/(x2(i+1) - x2(i))
851 ts(2) = (positions(2,ip) - y2(j))/(y2(j+1) - y2(j))
852 call cld_ntrp_linear_cell_interp(fvals, ts, lats(ip), ier)
853 iertot = iertot + ier
858 write(iertot_str,
'(i10)') iertot
859 ermesg =
'drifters_positions2geolonlat: ERROR '//trim(iertot_str)// &
860 &
' interpolation errors (domain out of bounds?)'
863 end subroutine drifters_positions2lonlat
867 subroutine drifters_print_checksums(self, pe, ermesg)
869 type(drifters_type) :: self
870 integer,
intent(in),
optional :: pe
871 character(len=*),
intent(out) :: ermesg
873 integer,
parameter :: i8 = selected_int_kind(13)
874 integer(i8) :: mold, chksum_pos, chksum_k1, chksum_k2, chksum_k3, chksum_k4
875 integer(i8) :: chksum_tot
880 if(.not.
present(pe))
then
886 if(me == _mpp_pe)
then
890 chksum_pos = transfer(sum(sum(self%core%positions(1:nd,1:np),1)), mold)
891 chksum_k1 = transfer(sum(sum(self%rk4_k1(1:nd,1:np),1)), mold)
892 chksum_k2 = transfer(sum(sum(self%rk4_k2(1:nd,1:np),1)), mold)
893 chksum_k3 = transfer(sum(sum(self%rk4_k3(1:nd,1:np),1)), mold)
894 chksum_k4 = transfer(sum(sum(self%rk4_k4(1:nd,1:np),1)), mold)
895 chksum_tot = chksum_pos + chksum_k1 + chksum_k2 + chksum_k3 +chksum_k4
897 print *,
'==============drifters checksums=========================='
898 print
'(a,i25,a,i6,a,e15.7)',
'==positions: ', chksum_pos,
' PE=', me,
' time = ', self%time
899 print
'(a,i25,a,i6,a,e15.7)',
'==k1 : ', chksum_k1,
' PE=', me,
' time = ', self%time
900 print
'(a,i25,a,i6,a,e15.7)',
'==k2 : ', chksum_k2,
' PE=', me,
' time = ', self%time
901 print
'(a,i25,a,i6,a,e15.7)',
'==k3 : ', chksum_k3,
' PE=', me,
' time = ', self%time
902 print
'(a,i25,a,i6,a,e15.7)',
'==k4 : ', chksum_k4,
' PE=', me,
' time = ', self%time
903 print
'(a,i25,a,i6,a,e15.7)',
'==total : ', chksum_tot,
' PE=', me,
' time = ', self%time
907 end subroutine drifters_print_checksums
909 subroutine drifters_reset_rk4(self, ermesg)
910 type(drifters_type) :: self
911 character(len=*),
intent(out) :: ermesg
917 if(
size(self%rk4_k1, 2) < self%core%np)
then
918 deallocate(self%rk4_k1, stat=ier)
919 allocate(self%rk4_k1(self%core%nd, self%core%npdim))
922 if(
size(self%rk4_k2, 2) < self%core%np)
then
923 deallocate(self%rk4_k2, stat=ier)
924 allocate(self%rk4_k2(self%core%nd, self%core%npdim))
927 if(
size(self%rk4_k3, 2) < self%core%np)
then
928 deallocate(self%rk4_k3, stat=ier)
929 allocate(self%rk4_k3(self%core%nd, self%core%npdim))
932 if(
size(self%rk4_k4, 2) < self%core%np)
then
933 deallocate(self%rk4_k4, stat=ier)
934 allocate(self%rk4_k4(self%core%nd, self%core%npdim))
938 if(
size(self%remove) < self%core%np)
then
939 deallocate(self%remove, stat=ier)
940 allocate(self%remove(self%core%npdim))
941 self%remove = .false.
944 if(
size(self%temp_pos, 2) < self%core%np)
then
945 deallocate(self%temp_pos, stat=ier)
946 nd =
size(self%input%velocity_names)
947 allocate(self%temp_pos(nd, self%core%npdim))
948 self%temp_pos = -huge(1.)
951 end subroutine drifters_reset_rk4
953 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.