7 use mom_coms,
only : pe_here, root_pe, num_pes, sum_across_pes
8 use mom_coms,
only : min_across_pes, max_across_pes
14 use iso_fortran_env,
only: error_unit
16 implicit none ;
private 18 public :: chksum0, zchksum
21 public :: mom_checksums_init
25 module procedure chksum_pair_h_2d, chksum_pair_h_3d
30 module procedure chksum_uv_2d, chksum_uv_3d
35 module procedure chksum_u_2d, chksum_u_3d
40 module procedure chksum_v_2d, chksum_v_3d
45 module procedure chksum_pair_b_2d, chksum_pair_b_3d
50 module procedure chksum_h_2d, chksum_h_3d
55 module procedure chksum_b_2d, chksum_b_3d
60 module procedure chksum_b_2d, chksum_b_3d
65 module procedure chksum1d, chksum2d, chksum3d
70 module procedure chk_sum_msg1, chk_sum_msg2, chk_sum_msg3, chk_sum_msg5
75 module procedure is_nan_0d, is_nan_1d, is_nan_2d, is_nan_3d
78 integer,
parameter :: bc_modulus = 1000000000
79 integer,
parameter :: default_shift=0
80 logical :: calculatestatistics=.true.
81 logical :: writechksums=.true.
82 logical :: checkfornans=.true.
88 subroutine chksum0(scalar, mesg, scale, logunit)
89 real,
intent(in) :: scalar
90 character(len=*),
intent(in) :: mesg
91 real,
optional,
intent(in) :: scale
92 integer,
optional,
intent(in) :: logunit
99 if (checkfornans .and.
is_nan(scalar)) &
100 call chksum_error(fatal,
'NaN detected: '//trim(mesg))
102 scaling = 1.0 ;
if (
present(scale)) scaling = scale
103 iounit = error_unit;
if(
present(logunit)) iounit = logunit
105 if (calculatestatistics)
then 106 rs = scaling * scalar
108 call chk_sum_msg(
" scalar:", rs, rs, rs, mesg, iounit)
111 if (.not. writechksums)
return 113 bc = mod(bitcount(abs(scaling * scalar)), bc_modulus)
117 end subroutine chksum0
121 subroutine zchksum(array, mesg, scale, logunit)
122 real,
dimension(:),
intent(in) :: array
123 character(len=*),
intent(in) :: mesg
124 real,
optional,
intent(in) :: scale
125 integer,
optional,
intent(in) :: logunit
127 real,
allocatable,
dimension(:) :: rescaled_array
131 real :: amean, amin, amax
134 if (checkfornans)
then 136 call chksum_error(fatal,
'NaN detected: '//trim(mesg))
139 scaling = 1.0 ;
if (
present(scale)) scaling = scale
140 iounit = error_unit;
if(
present(logunit)) iounit = logunit
142 if (calculatestatistics)
then 143 if (
present(scale))
then 144 allocate(rescaled_array(lbound(array,1):ubound(array,1)))
145 rescaled_array(:) = 0.0
146 do k=1,
size(array, 1)
147 rescaled_array(k) = scale * array(k)
150 call substats(rescaled_array, amean, amin, amax)
151 deallocate(rescaled_array)
153 call substats(array, amean, amin, amax)
157 call chk_sum_msg(
" column:", amean, amin, amax, mesg, iounit)
160 if (.not. writechksums)
return 162 bc0 = subchk(array, scaling)
163 if (is_root_pe())
call chk_sum_msg(
" column:", bc0, mesg, iounit)
167 integer function subchk(array, scale)
168 real,
dimension(:),
intent(in) :: array
169 real,
intent(in) :: scale
172 do k=lbound(array, 1), ubound(array, 1)
173 bc = bitcount(abs(scale * array(k)))
176 subchk=mod(subchk, bc_modulus)
179 subroutine substats(array, aMean, aMin, aMax)
180 real,
dimension(:),
intent(in) :: array
181 real,
intent(out) :: amean
182 real,
intent(out) :: amin
183 real,
intent(out) :: amax
190 do k=lbound(array,1), ubound(array,1)
191 amin = min(amin, array(k))
192 amax = max(amax, array(k))
195 amean = sum(array(:)) /
real(n)
196 end subroutine substats
197 end subroutine zchksum
200 subroutine chksum_pair_h_2d(mesg, arrayA, arrayB, HI, haloshift, omit_corners, &
201 scale, logunit, scalar_pair)
202 character(len=*),
intent(in) :: mesg
203 type(hor_index_type),
target,
intent(in) :: HI
204 real,
dimension(HI%isd:,HI%jsd:),
target,
intent(in) :: arrayA
205 real,
dimension(HI%isd:,HI%jsd:),
target,
intent(in) :: arrayB
206 integer,
optional,
intent(in) :: haloshift
207 logical,
optional,
intent(in) :: omit_corners
208 real,
optional,
intent(in) :: scale
209 integer,
optional,
intent(in) :: logunit
210 logical,
optional,
intent(in) :: scalar_pair
212 logical :: vector_pair
214 type(hor_index_type),
pointer :: HI_in
215 real,
dimension(:,:),
pointer :: arrayA_in, arrayB_in
218 if (
present(scalar_pair)) vector_pair = .not. scalar_pair
221 if (modulo(turns, 4) /= 0)
then 224 call rotate_hor_index(hi, -turns, hi_in)
225 allocate(arraya_in(hi_in%isd:hi_in%ied, hi_in%jsd:hi_in%jed))
226 allocate(arrayb_in(hi_in%isd:hi_in%ied, hi_in%jsd:hi_in%jed))
228 if (vector_pair)
then 229 call rotate_vector(arraya, arrayb, -turns, arraya_in, arrayb_in)
239 if (
present(haloshift))
then 240 call chksum_h_2d(arraya_in,
'x '//mesg, hi_in, haloshift, omit_corners, &
241 scale=scale, logunit=logunit)
242 call chksum_h_2d(arrayb_in,
'y '//mesg, hi_in, haloshift, omit_corners, &
243 scale=scale, logunit=logunit)
245 call chksum_h_2d(arraya_in,
'x '//mesg, hi_in, scale=scale, logunit=logunit)
246 call chksum_h_2d(arrayb_in,
'y '//mesg, hi_in, scale=scale, logunit=logunit)
248 end subroutine chksum_pair_h_2d
251 subroutine chksum_pair_h_3d(mesg, arrayA, arrayB, HI, haloshift, omit_corners, &
252 scale, logunit, scalar_pair)
253 character(len=*),
intent(in) :: mesg
254 type(hor_index_type),
target,
intent(in) :: HI
255 real,
dimension(HI%isd:,HI%jsd:, :),
target,
intent(in) :: arrayA
256 real,
dimension(HI%isd:,HI%jsd:, :),
target,
intent(in) :: arrayB
257 integer,
optional,
intent(in) :: haloshift
258 logical,
optional,
intent(in) :: omit_corners
259 real,
optional,
intent(in) :: scale
260 integer,
optional,
intent(in) :: logunit
262 logical,
optional,
intent(in) :: scalar_pair
264 logical :: vector_pair
266 type(hor_index_type),
pointer :: HI_in
267 real,
dimension(:,:,:),
pointer :: arrayA_in, arrayB_in
270 if (
present(scalar_pair)) vector_pair = .not. scalar_pair
273 if (modulo(turns, 4) /= 0)
then 276 call rotate_hor_index(hi, -turns, hi_in)
277 allocate(arraya_in(hi_in%isd:hi_in%ied, hi_in%jsd:hi_in%jed,
size(arraya, 3)))
278 allocate(arrayb_in(hi_in%isd:hi_in%ied, hi_in%jsd:hi_in%jed,
size(arrayb, 3)))
280 if (vector_pair)
then 281 call rotate_vector(arraya, arrayb, -turns, arraya_in, arrayb_in)
291 if (
present(haloshift))
then 292 call chksum_h_3d(arraya_in,
'x '//mesg, hi_in, haloshift, omit_corners, &
293 scale=scale, logunit=logunit)
294 call chksum_h_3d(arrayb_in,
'y '//mesg, hi_in, haloshift, omit_corners, &
295 scale=scale, logunit=logunit)
297 call chksum_h_3d(arraya_in,
'x '//mesg, hi_in, scale=scale, logunit=logunit)
298 call chksum_h_3d(arrayb_in,
'y '//mesg, hi_in, scale=scale, logunit=logunit)
302 end subroutine chksum_pair_h_3d
305 subroutine chksum_h_2d(array_m, mesg, HI_m, haloshift, omit_corners, scale, logunit)
306 type(hor_index_type),
target,
intent(in) :: HI_m
307 real,
dimension(HI_m%isd:,HI_m%jsd:),
target,
intent(in) :: array_m
308 character(len=*),
intent(in) :: mesg
309 integer,
optional,
intent(in) :: haloshift
310 logical,
optional,
intent(in) :: omit_corners
311 real,
optional,
intent(in) :: scale
312 integer,
optional,
intent(in) :: logunit
314 real,
pointer :: array(:,:)
315 real,
allocatable,
dimension(:,:) :: rescaled_array
316 type(hor_index_type),
pointer :: HI
320 real :: aMean, aMin, aMax
321 integer :: bc0, bcSW, bcSE, bcNW, bcNE, hshift
322 integer :: bcN, bcS, bcE, bcW
323 logical :: do_corners
328 if (modulo(turns, 4) /= 0)
then 330 call rotate_hor_index(hi_m, -turns, hi)
331 allocate(array(hi%isd:hi%ied, hi%jsd:hi%jed))
338 if (checkfornans)
then 339 if (
is_nan(array(hi%isc:hi%iec,hi%jsc:hi%jec))) &
340 call chksum_error(fatal,
'NaN detected: '//trim(mesg))
345 scaling = 1.0 ;
if (
present(scale)) scaling = scale
346 iounit = error_unit;
if(
present(logunit)) iounit = logunit
348 if (calculatestatistics)
then 349 if (
present(scale))
then 350 allocate( rescaled_array(lbound(array,1):ubound(array,1), &
351 lbound(array,2):ubound(array,2)) )
352 rescaled_array(:,:) = 0.0
353 do j=hi%jsc,hi%jec ;
do i=hi%isc,hi%iec
354 rescaled_array(i,j) = scale*array(i,j)
356 call substats(hi, rescaled_array, amean, amin, amax)
357 deallocate(rescaled_array)
359 call substats(hi, array, amean, amin, amax)
363 call chk_sum_msg(
"h-point:", amean, amin, amax, mesg, iounit)
366 if (.not.writechksums)
return 368 hshift = default_shift
369 if (
present(haloshift)) hshift = haloshift
370 if (hshift<0) hshift = hi%ied-hi%iec
372 if ( hi%isc-hshift<hi%isd .or. hi%iec+hshift>hi%ied .or. &
373 hi%jsc-hshift<hi%jsd .or. hi%jec+hshift>hi%jed )
then 374 write(0,*)
'chksum_h_2d: haloshift =',hshift
375 write(0,*)
'chksum_h_2d: isd,isc,iec,ied=',hi%isd,hi%isc,hi%iec,hi%ied
376 write(0,*)
'chksum_h_2d: jsd,jsc,jec,jed=',hi%jsd,hi%jsc,hi%jec,hi%jed
377 call chksum_error(fatal,
'Error in chksum_h_2d '//trim(mesg))
380 bc0 = subchk(array, hi, 0, 0, scaling)
383 if (is_root_pe())
call chk_sum_msg(
"h-point:", bc0, mesg, iounit)
387 do_corners = .true. ;
if (
present(omit_corners)) do_corners = .not.omit_corners
390 bcsw = subchk(array, hi, -hshift, -hshift, scaling)
391 bcse = subchk(array, hi, hshift, -hshift, scaling)
392 bcnw = subchk(array, hi, -hshift, hshift, scaling)
393 bcne = subchk(array, hi, hshift, hshift, scaling)
396 call chk_sum_msg(
"h-point:", bc0, bcsw, bcse, bcnw, bcne, mesg, iounit)
398 bcs = subchk(array, hi, 0, -hshift, scaling)
399 bce = subchk(array, hi, hshift, 0, scaling)
400 bcw = subchk(array, hi, -hshift, 0, scaling)
401 bcn = subchk(array, hi, 0, hshift, scaling)
404 call chk_sum_msg_nsew(
"h-point:", bc0, bcn, bcs, bce, bcw, mesg, iounit)
408 integer function subchk(array, HI, di, dj, scale)
409 type(hor_index_type),
intent(in) :: HI
410 real,
dimension(HI%isd:,HI%jsd:),
intent(in) :: array
411 integer,
intent(in) :: di
412 integer,
intent(in) :: dj
413 real,
intent(in) :: scale
416 do j=hi%jsc+dj,hi%jec+dj;
do i=hi%isc+di,hi%iec+di
417 bc = bitcount(abs(scale*array(i,j)))
420 call sum_across_pes(subchk)
421 subchk=mod(subchk, bc_modulus)
424 subroutine substats(HI, array, aMean, aMin, aMax)
425 type(hor_index_type),
intent(in) :: HI
426 real,
dimension(HI%isd:,HI%jsd:),
intent(in) :: array
427 real,
intent(out) :: aMean
428 real,
intent(out) :: aMin
429 real,
intent(out) :: aMax
433 amin = array(hi%isc,hi%jsc)
434 amax = array(hi%isc,hi%jsc)
436 do j=hi%jsc,hi%jec ;
do i=hi%isc,hi%iec
437 amin = min(amin, array(i,j))
438 amax = max(amax, array(i,j))
442 call sum_across_pes(n)
443 call min_across_pes(amin)
444 call max_across_pes(amax)
445 amean = amean /
real(n)
446 end subroutine substats
448 end subroutine chksum_h_2d
451 subroutine chksum_pair_b_2d(mesg, arrayA, arrayB, HI, haloshift, symmetric, &
452 omit_corners, scale, logunit, scalar_pair)
453 character(len=*),
intent(in) :: mesg
454 type(hor_index_type),
target,
intent(in) :: HI
455 real,
dimension(HI%isd:,HI%jsd:),
target,
intent(in) :: arrayA
456 real,
dimension(HI%isd:,HI%jsd:),
target,
intent(in) :: arrayB
457 logical,
optional,
intent(in) :: symmetric
459 integer,
optional,
intent(in) :: haloshift
460 logical,
optional,
intent(in) :: omit_corners
461 real,
optional,
intent(in) :: scale
462 integer,
optional,
intent(in) :: logunit
463 logical,
optional,
intent(in) :: scalar_pair
467 logical :: vector_pair
469 type(hor_index_type),
pointer :: HI_in
470 real,
dimension(:,:),
pointer :: arrayA_in, arrayB_in
473 if (
present(scalar_pair)) vector_pair = .not. scalar_pair
476 if (modulo(turns, 4) /= 0)
then 479 call rotate_hor_index(hi, -turns, hi_in)
480 allocate(arraya_in(hi_in%IsdB:hi_in%IedB, hi_in%JsdB:hi_in%JedB))
481 allocate(arrayb_in(hi_in%IsdB:hi_in%IedB, hi_in%JsdB:hi_in%JedB))
483 if (vector_pair)
then 484 call rotate_vector(arraya, arrayb, -turns, arraya_in, arrayb_in)
494 sym = .false. ;
if (
present(symmetric)) sym = symmetric
496 if (
present(haloshift))
then 497 call chksum_b_2d(arraya_in,
'x '//mesg, hi_in, haloshift, symmetric=sym, &
498 omit_corners=omit_corners, scale=scale, logunit=logunit)
499 call chksum_b_2d(arrayb_in,
'y '//mesg, hi_in, haloshift, symmetric=sym, &
500 omit_corners=omit_corners, scale=scale, logunit=logunit)
502 call chksum_b_2d(arraya_in,
'x '//mesg, hi_in, symmetric=sym, scale=scale, &
504 call chksum_b_2d(arrayb_in,
'y '//mesg, hi_in, symmetric=sym, scale=scale, &
508 end subroutine chksum_pair_b_2d
511 subroutine chksum_pair_b_3d(mesg, arrayA, arrayB, HI, haloshift, symmetric, &
512 omit_corners, scale, logunit, scalar_pair)
513 character(len=*),
intent(in) :: mesg
514 type(hor_index_type),
target,
intent(in) :: HI
515 real,
dimension(HI%IsdB:,HI%JsdB:, :),
target,
intent(in) :: arrayA
516 real,
dimension(HI%IsdB:,HI%JsdB:, :),
target,
intent(in) :: arrayB
517 integer,
optional,
intent(in) :: haloshift
518 logical,
optional,
intent(in) :: symmetric
520 logical,
optional,
intent(in) :: omit_corners
521 real,
optional,
intent(in) :: scale
522 integer,
optional,
intent(in) :: logunit
523 logical,
optional,
intent(in) :: scalar_pair
527 logical :: vector_pair
529 type(hor_index_type),
pointer :: HI_in
530 real,
dimension(:,:,:),
pointer :: arrayA_in, arrayB_in
533 if (
present(scalar_pair)) vector_pair = .not. scalar_pair
536 if (modulo(turns, 4) /= 0)
then 539 call rotate_hor_index(hi, -turns, hi_in)
540 allocate(arraya_in(hi_in%IsdB:hi_in%IedB, hi_in%JsdB:hi_in%JedB,
size(arraya, 3)))
541 allocate(arrayb_in(hi_in%IsdB:hi_in%IedB, hi_in%JsdB:hi_in%JedB,
size(arrayb, 3)))
543 if (vector_pair)
then 544 call rotate_vector(arraya, arrayb, -turns, arraya_in, arrayb_in)
554 if (
present(haloshift))
then 555 call chksum_b_3d(arraya_in,
'x '//mesg, hi_in, haloshift, symmetric, &
556 omit_corners, scale=scale, logunit=logunit)
557 call chksum_b_3d(arrayb_in,
'y '//mesg, hi_in, haloshift, symmetric, &
558 omit_corners, scale=scale, logunit=logunit)
560 call chksum_b_3d(arraya_in,
'x '//mesg, hi_in, symmetric=symmetric, scale=scale, &
562 call chksum_b_3d(arrayb_in,
'y '//mesg, hi_in, symmetric=symmetric, scale=scale, &
565 end subroutine chksum_pair_b_3d
568 subroutine chksum_b_2d(array_m, mesg, HI_m, haloshift, symmetric, omit_corners, &
570 type(hor_index_type),
target,
intent(in) :: HI_m
571 real,
dimension(HI_m%IsdB:,HI_m%JsdB:), &
572 target,
intent(in) :: array_m
573 character(len=*),
intent(in) :: mesg
574 integer,
optional,
intent(in) :: haloshift
575 logical,
optional,
intent(in) :: symmetric
577 logical,
optional,
intent(in) :: omit_corners
578 real,
optional,
intent(in) :: scale
579 integer,
optional,
intent(in) :: logunit
581 real,
pointer :: array(:,:)
582 real,
allocatable,
dimension(:,:) :: rescaled_array
583 type(hor_index_type),
pointer :: HI
586 integer :: i, j, Is, Js
587 real :: aMean, aMin, aMax
588 integer :: bc0, bcSW, bcSE, bcNW, bcNE, hshift
589 integer :: bcN, bcS, bcE, bcW
590 logical :: do_corners, sym, sym_stats
595 if (modulo(turns, 4) /= 0)
then 597 call rotate_hor_index(hi_m, -turns, hi)
598 allocate(array(hi%IsdB:hi%IedB, hi%JsdB:hi%JedB))
605 if (checkfornans)
then 606 if (
is_nan(array(hi%IscB:hi%IecB,hi%JscB:hi%JecB))) &
607 call chksum_error(fatal,
'NaN detected: '//trim(mesg))
612 scaling = 1.0 ;
if (
present(scale)) scaling = scale
613 iounit = error_unit;
if(
present(logunit)) iounit = logunit
614 sym_stats = .false. ;
if (
present(symmetric)) sym_stats = symmetric
615 if (
present(haloshift))
then ;
if (haloshift > 0) sym_stats = .true. ;
endif 617 if (calculatestatistics)
then 618 if (
present(scale))
then 619 allocate( rescaled_array(lbound(array,1):ubound(array,1), &
620 lbound(array,2):ubound(array,2)) )
621 rescaled_array(:,:) = 0.0
622 is = hi%isc ;
if (sym_stats) is = hi%isc-1
623 js = hi%jsc ;
if (sym_stats) js = hi%jsc-1
624 do j=js,hi%JecB ;
do i=is,hi%IecB
625 rescaled_array(i,j) = scale*array(i,j)
627 call substats(hi, rescaled_array, sym_stats, amean, amin, amax)
628 deallocate(rescaled_array)
630 call substats(hi, array, sym_stats, amean, amin, amax)
633 call chk_sum_msg(
"B-point:", amean, amin, amax, mesg, iounit)
636 if (.not.writechksums)
return 638 hshift = default_shift
639 if (
present(haloshift)) hshift = haloshift
640 if (hshift<0) hshift = hi%ied-hi%iec
642 if ( hi%iscB-hshift<hi%isdB .or. hi%iecB+hshift>hi%iedB .or. &
643 hi%jscB-hshift<hi%jsdB .or. hi%jecB+hshift>hi%jedB )
then 644 write(0,*)
'chksum_B_2d: haloshift =',hshift
645 write(0,*)
'chksum_B_2d: isd,isc,iec,ied=',hi%isdB,hi%iscB,hi%iecB,hi%iedB
646 write(0,*)
'chksum_B_2d: jsd,jsc,jec,jed=',hi%jsdB,hi%jscB,hi%jecB,hi%jedB
647 call chksum_error(fatal,
'Error in chksum_B_2d '//trim(mesg))
650 bc0 = subchk(array, hi, 0, 0, scaling)
652 sym = .false. ;
if (
present(symmetric)) sym = symmetric
654 if ((hshift==0) .and. .not.sym)
then 655 if (is_root_pe())
call chk_sum_msg(
"B-point:", bc0, mesg, iounit)
659 do_corners = .true. ;
if (
present(omit_corners)) do_corners = .not.omit_corners
663 bcsw = subchk(array, hi, -hshift-1, -hshift-1, scaling)
664 bcse = subchk(array, hi, hshift, -hshift-1, scaling)
665 bcnw = subchk(array, hi, -hshift-1, hshift, scaling)
667 bcsw = subchk(array, hi, -hshift, -hshift, scaling)
668 bcse = subchk(array, hi, hshift, -hshift, scaling)
669 bcnw = subchk(array, hi, -hshift, hshift, scaling)
671 bcne = subchk(array, hi, hshift, hshift, scaling)
674 call chk_sum_msg(
"B-point:", bc0, bcsw, bcse, bcnw, bcne, mesg, iounit)
676 bcs = subchk(array, hi, 0, -hshift, scaling)
677 bce = subchk(array, hi, hshift, 0, scaling)
678 bcw = subchk(array, hi, -hshift, 0, scaling)
679 bcn = subchk(array, hi, 0, hshift, scaling)
682 call chk_sum_msg_nsew(
"B-point:", bc0, bcn, bcs, bce, bcw, mesg, iounit)
687 integer function subchk(array, HI, di, dj, scale)
688 type(hor_index_type),
intent(in) :: HI
689 real,
dimension(HI%IsdB:,HI%JsdB:),
intent(in) :: array
690 integer,
intent(in) :: di
691 integer,
intent(in) :: dj
692 real,
intent(in) :: scale
696 do j=hi%jsc+dj,hi%jec+dj;
do i=hi%isc+di,hi%iec+di
697 bc = bitcount(abs(scale*array(i,j)))
700 call sum_across_pes(subchk)
701 subchk=mod(subchk, bc_modulus)
704 subroutine substats(HI, array, sym_stats, aMean, aMin, aMax)
705 type(hor_index_type),
intent(in) :: HI
706 real,
dimension(HI%IsdB:,HI%JsdB:),
intent(in) :: array
707 logical,
intent(in) :: sym_stats
709 real,
intent(out) :: aMean
710 real,
intent(out) :: aMin
711 real,
intent(out) :: aMax
713 integer :: i, j, n, IsB, JsB
715 isb = hi%isc ;
if (sym_stats) isb = hi%isc-1
716 jsb = hi%jsc ;
if (sym_stats) jsb = hi%jsc-1
718 amin = array(hi%isc,hi%jsc) ; amax = amin
719 do j=jsb,hi%JecB ;
do i=isb,hi%IecB
720 amin = min(amin, array(i,j))
721 amax = max(amax, array(i,j))
725 n = (1 + hi%jec - hi%jsc) * (1 + hi%iec - hi%isc)
726 call sum_across_pes(n)
727 call min_across_pes(amin)
728 call max_across_pes(amax)
729 amean = amean /
real(n)
730 end subroutine substats
732 end subroutine chksum_b_2d
735 subroutine chksum_uv_2d(mesg, arrayU, arrayV, HI, haloshift, symmetric, &
736 omit_corners, scale, logunit, scalar_pair)
737 character(len=*),
intent(in) :: mesg
738 type(hor_index_type),
target,
intent(in) :: HI
739 real,
dimension(HI%IsdB:,HI%jsd:),
target,
intent(in) :: arrayU
740 real,
dimension(HI%isd:,HI%JsdB:),
target,
intent(in) :: arrayV
741 integer,
optional,
intent(in) :: haloshift
742 logical,
optional,
intent(in) :: symmetric
744 logical,
optional,
intent(in) :: omit_corners
745 real,
optional,
intent(in) :: scale
746 integer,
optional,
intent(in) :: logunit
747 logical,
optional,
intent(in) :: scalar_pair
749 logical :: vector_pair
751 type(hor_index_type),
pointer :: HI_in
752 real,
dimension(:,:),
pointer :: arrayU_in, arrayV_in
755 if (
present(scalar_pair)) vector_pair = .not. scalar_pair
758 if (modulo(turns, 4) /= 0)
then 761 call rotate_hor_index(hi, -turns, hi_in)
762 allocate(arrayu_in(hi_in%IsdB:hi_in%IedB, hi_in%jsd:hi_in%jed))
763 allocate(arrayv_in(hi_in%isd:hi_in%ied, hi_in%JsdB:hi_in%JedB))
765 if (vector_pair)
then 766 call rotate_vector(arrayu, arrayv, -turns, arrayu_in, arrayv_in)
776 if (
present(haloshift))
then 777 call chksum_u_2d(arrayu_in,
'u '//mesg, hi_in, haloshift, symmetric, &
778 omit_corners, scale=scale, logunit=logunit)
779 call chksum_v_2d(arrayv_in,
'v '//mesg, hi_in, haloshift, symmetric, &
780 omit_corners, scale=scale, logunit=logunit)
782 call chksum_u_2d(arrayu_in,
'u '//mesg, hi_in, symmetric=symmetric, &
783 scale=scale, logunit=logunit)
784 call chksum_v_2d(arrayv_in,
'v '//mesg, hi_in, symmetric=symmetric, &
785 scale=scale, logunit=logunit)
787 end subroutine chksum_uv_2d
790 subroutine chksum_uv_3d(mesg, arrayU, arrayV, HI, haloshift, symmetric, &
791 omit_corners, scale, logunit, scalar_pair)
792 character(len=*),
intent(in) :: mesg
793 type(hor_index_type),
target,
intent(in) :: HI
794 real,
dimension(HI%IsdB:,HI%jsd:,:),
target,
intent(in) :: arrayU
795 real,
dimension(HI%isd:,HI%JsdB:,:),
target,
intent(in) :: arrayV
796 integer,
optional,
intent(in) :: haloshift
797 logical,
optional,
intent(in) :: symmetric
799 logical,
optional,
intent(in) :: omit_corners
800 real,
optional,
intent(in) :: scale
801 integer,
optional,
intent(in) :: logunit
802 logical,
optional,
intent(in) :: scalar_pair
804 logical :: vector_pair
806 type(hor_index_type),
pointer :: HI_in
807 real,
dimension(:,:,:),
pointer :: arrayU_in, arrayV_in
810 if (
present(scalar_pair)) vector_pair = .not. scalar_pair
813 if (modulo(turns, 4) /= 0)
then 816 call rotate_hor_index(hi, -turns, hi_in)
817 allocate(arrayu_in(hi_in%IsdB:hi_in%IedB, hi_in%jsd:hi_in%jed,
size(arrayu, 3)))
818 allocate(arrayv_in(hi_in%isd:hi_in%ied, hi_in%JsdB:hi_in%JedB,
size(arrayv, 3)))
820 if (vector_pair)
then 821 call rotate_vector(arrayu, arrayv, -turns, arrayu_in, arrayv_in)
831 if (
present(haloshift))
then 832 call chksum_u_3d(arrayu_in,
'u '//mesg, hi_in, haloshift, symmetric, &
833 omit_corners, scale=scale, logunit=logunit)
834 call chksum_v_3d(arrayv_in,
'v '//mesg, hi_in, haloshift, symmetric, &
835 omit_corners, scale=scale, logunit=logunit)
837 call chksum_u_3d(arrayu_in,
'u '//mesg, hi_in, symmetric=symmetric, &
838 scale=scale, logunit=logunit)
839 call chksum_v_3d(arrayv_in,
'v '//mesg, hi_in, symmetric=symmetric, &
840 scale=scale, logunit=logunit)
842 end subroutine chksum_uv_3d
845 subroutine chksum_u_2d(array_m, mesg, HI_m, haloshift, symmetric, omit_corners, &
847 type(hor_index_type),
target,
intent(in) :: HI_m
848 real,
dimension(HI_m%IsdB:,HI_m%jsd:),
target,
intent(in) :: array_m
849 character(len=*),
intent(in) :: mesg
850 integer,
optional,
intent(in) :: haloshift
851 logical,
optional,
intent(in) :: symmetric
853 logical,
optional,
intent(in) :: omit_corners
854 real,
optional,
intent(in) :: scale
855 integer,
optional,
intent(in) :: logunit
857 real,
pointer :: array(:,:)
858 real,
allocatable,
dimension(:,:) :: rescaled_array
859 type(hor_index_type),
pointer :: HI
863 real :: aMean, aMin, aMax
864 integer :: bc0, bcSW, bcSE, bcNW, bcNE, hshift
865 integer :: bcN, bcS, bcE, bcW
866 logical :: do_corners, sym, sym_stats
871 if (modulo(turns, 4) /= 0)
then 873 call rotate_hor_index(hi_m, -turns, hi)
874 if (modulo(turns, 2) /= 0)
then 876 allocate(array(hi%isd:hi%ied, hi%JsdB:hi%JedB))
878 call vchksum(array, mesg, hi, haloshift, symmetric, omit_corners, scale, logunit)
881 allocate(array(hi%IsdB:hi%IedB, hi%jsd:hi%jed))
889 if (checkfornans)
then 890 if (
is_nan(array(hi%IscB:hi%IecB,hi%jsc:hi%jec))) &
891 call chksum_error(fatal,
'NaN detected: '//trim(mesg))
896 scaling = 1.0 ;
if (
present(scale)) scaling = scale
897 iounit = error_unit;
if(
present(logunit)) iounit = logunit
898 sym_stats = .false. ;
if (
present(symmetric)) sym_stats = symmetric
899 if (
present(haloshift))
then ;
if (haloshift > 0) sym_stats = .true. ;
endif 901 if (calculatestatistics)
then 902 if (
present(scale))
then 903 allocate( rescaled_array(lbound(array,1):ubound(array,1), &
904 lbound(array,2):ubound(array,2)) )
905 rescaled_array(:,:) = 0.0
906 is = hi%isc ;
if (sym_stats) is = hi%isc-1
907 do j=hi%jsc,hi%jec ;
do i=is,hi%IecB
908 rescaled_array(i,j) = scale*array(i,j)
910 call substats(hi, rescaled_array, sym_stats, amean, amin, amax)
911 deallocate(rescaled_array)
913 call substats(hi, array, sym_stats, amean, amin, amax)
917 call chk_sum_msg(
"u-point:", amean, amin, amax, mesg, iounit)
920 if (.not.writechksums)
return 922 hshift = default_shift
923 if (
present(haloshift)) hshift = haloshift
924 if (hshift<0) hshift = hi%iedB-hi%iecB
926 if ( hi%iscB-hshift<hi%isdB .or. hi%iecB+hshift>hi%iedB .or. &
927 hi%jsc-hshift<hi%jsd .or. hi%jec+hshift>hi%jed )
then 928 write(0,*)
'chksum_u_2d: haloshift =',hshift
929 write(0,*)
'chksum_u_2d: isd,isc,iec,ied=',hi%isdB,hi%iscB,hi%iecB,hi%iedB
930 write(0,*)
'chksum_u_2d: jsd,jsc,jec,jed=',hi%jsd,hi%jsc,hi%jec,hi%jed
931 call chksum_error(fatal,
'Error in chksum_u_2d '//trim(mesg))
934 bc0 = subchk(array, hi, 0, 0, scaling)
936 sym = .false. ;
if (
present(symmetric)) sym = symmetric
938 if ((hshift==0) .and. .not.sym)
then 939 if (is_root_pe())
call chk_sum_msg(
"u-point:", bc0, mesg, iounit)
943 do_corners = .true. ;
if (
present(omit_corners)) do_corners = .not.omit_corners
946 bcw = subchk(array, hi, -hshift-1, 0, scaling)
947 if (is_root_pe())
call chk_sum_msg_w(
"u-point:", bc0, bcw, mesg, iounit)
948 elseif (do_corners)
then 950 bcsw = subchk(array, hi, -hshift-1, -hshift, scaling)
951 bcnw = subchk(array, hi, -hshift-1, hshift, scaling)
953 bcsw = subchk(array, hi, -hshift, -hshift, scaling)
954 bcnw = subchk(array, hi, -hshift, hshift, scaling)
956 bcse = subchk(array, hi, hshift, -hshift, scaling)
957 bcne = subchk(array, hi, hshift, hshift, scaling)
960 call chk_sum_msg(
"u-point:", bc0, bcsw, bcse, bcnw, bcne, mesg, iounit)
962 bcs = subchk(array, hi, 0, -hshift, scaling)
963 bce = subchk(array, hi, hshift, 0, scaling)
965 bcw = subchk(array, hi, -hshift-1, 0, scaling)
967 bcw = subchk(array, hi, -hshift, 0, scaling)
969 bcn = subchk(array, hi, 0, hshift, scaling)
972 call chk_sum_msg_nsew(
"u-point:", bc0, bcn, bcs, bce, bcw, mesg, iounit)
977 integer function subchk(array, HI, di, dj, scale)
978 type(hor_index_type),
intent(in) :: HI
979 real,
dimension(HI%IsdB:,HI%jsd:),
intent(in) :: array
980 integer,
intent(in) :: di
981 integer,
intent(in) :: dj
982 real,
intent(in) :: scale
986 do j=hi%jsc+dj,hi%jec+dj;
do i=hi%isc+di,hi%iec+di
987 bc = bitcount(abs(scale*array(i,j)))
990 call sum_across_pes(subchk)
991 subchk=mod(subchk, bc_modulus)
994 subroutine substats(HI, array, sym_stats, aMean, aMin, aMax)
995 type(hor_index_type),
intent(in) :: HI
996 real,
dimension(HI%IsdB:,HI%jsd:),
intent(in) :: array
997 logical,
intent(in) :: sym_stats
999 real,
intent(out) :: aMean
1000 real,
intent(out) :: aMin
1001 real,
intent(out) :: aMax
1003 integer :: i, j, n, IsB
1005 isb = hi%isc ;
if (sym_stats) isb = hi%isc-1
1007 amin = array(hi%isc,hi%jsc) ; amax = amin
1008 do j=hi%jsc,hi%jec ;
do i=isb,hi%IecB
1009 amin = min(amin, array(i,j))
1010 amax = max(amax, array(i,j))
1014 n = (1 + hi%jec - hi%jsc) * (1 + hi%iec - hi%isc)
1015 call sum_across_pes(n)
1016 call min_across_pes(amin)
1017 call max_across_pes(amax)
1018 amean = amean /
real(n)
1019 end subroutine substats
1021 end subroutine chksum_u_2d
1024 subroutine chksum_v_2d(array_m, mesg, HI_m, haloshift, symmetric, omit_corners, &
1026 type(hor_index_type),
target,
intent(in) :: HI_m
1027 real,
dimension(HI_m%isd:,HI_m%JsdB:),
target,
intent(in) :: array_m
1028 character(len=*),
intent(in) :: mesg
1029 integer,
optional,
intent(in) :: haloshift
1030 logical,
optional,
intent(in) :: symmetric
1032 logical,
optional,
intent(in) :: omit_corners
1033 real,
optional,
intent(in) :: scale
1034 integer,
optional,
intent(in) :: logunit
1036 real,
pointer :: array(:,:)
1037 real,
allocatable,
dimension(:,:) :: rescaled_array
1038 type(hor_index_type),
pointer :: HI
1042 real :: aMean, aMin, aMax
1043 integer :: bc0, bcSW, bcSE, bcNW, bcNE, hshift
1044 integer :: bcN, bcS, bcE, bcW
1045 logical :: do_corners, sym, sym_stats
1050 if (modulo(turns, 4) /= 0)
then 1052 call rotate_hor_index(hi_m, -turns, hi)
1053 if (modulo(turns, 2) /= 0)
then 1055 allocate(array(hi%IsdB:hi%IedB, hi%jsd:hi%jed))
1057 call uchksum(array, mesg, hi, haloshift, symmetric, omit_corners, scale, logunit)
1060 allocate(array(hi%isd:hi%ied, hi%JsdB:hi%JedB))
1068 if (checkfornans)
then 1069 if (
is_nan(array(hi%isc:hi%iec,hi%JscB:hi%JecB))) &
1070 call chksum_error(fatal,
'NaN detected: '//trim(mesg))
1075 scaling = 1.0 ;
if (
present(scale)) scaling = scale
1076 iounit = error_unit;
if(
present(logunit)) iounit = logunit
1077 sym_stats = .false. ;
if (
present(symmetric)) sym_stats = symmetric
1078 if (
present(haloshift))
then ;
if (haloshift > 0) sym_stats = .true. ;
endif 1080 if (calculatestatistics)
then 1081 if (
present(scale))
then 1082 allocate( rescaled_array(lbound(array,1):ubound(array,1), &
1083 lbound(array,2):ubound(array,2)) )
1084 rescaled_array(:,:) = 0.0
1085 js = hi%jsc ;
if (sym_stats) js = hi%jsc-1
1086 do j=js,hi%JecB ;
do i=hi%isc,hi%iec
1087 rescaled_array(i,j) = scale*array(i,j)
1089 call substats(hi, rescaled_array, sym_stats, amean, amin, amax)
1090 deallocate(rescaled_array)
1092 call substats(hi, array, sym_stats, amean, amin, amax)
1096 call chk_sum_msg(
"v-point:", amean, amin, amax, mesg, iounit)
1099 if (.not.writechksums)
return 1101 hshift = default_shift
1102 if (
present(haloshift)) hshift = haloshift
1103 if (hshift<0) hshift = hi%ied-hi%iec
1105 if ( hi%isc-hshift<hi%isd .or. hi%iec+hshift>hi%ied .or. &
1106 hi%jscB-hshift<hi%jsdB .or. hi%jecB+hshift>hi%jedB )
then 1107 write(0,*)
'chksum_v_2d: haloshift =',hshift
1108 write(0,*)
'chksum_v_2d: isd,isc,iec,ied=',hi%isd,hi%isc,hi%iec,hi%ied
1109 write(0,*)
'chksum_v_2d: jsd,jsc,jec,jed=',hi%jsdB,hi%jscB,hi%jecB,hi%jedB
1110 call chksum_error(fatal,
'Error in chksum_v_2d '//trim(mesg))
1113 bc0 = subchk(array, hi, 0, 0, scaling)
1115 sym = .false. ;
if (
present(symmetric)) sym = symmetric
1117 if ((hshift==0) .and. .not.sym)
then 1118 if (is_root_pe())
call chk_sum_msg(
"v-point:", bc0, mesg, iounit)
1122 do_corners = .true. ;
if (
present(omit_corners)) do_corners = .not.omit_corners
1125 bcs = subchk(array, hi, 0, -hshift-1, scaling)
1126 if (is_root_pe())
call chk_sum_msg_s(
"v-point:", bc0, bcs, mesg, iounit)
1127 elseif (do_corners)
then 1129 bcsw = subchk(array, hi, -hshift, -hshift-1, scaling)
1130 bcse = subchk(array, hi, hshift, -hshift-1, scaling)
1132 bcsw = subchk(array, hi, -hshift, -hshift, scaling)
1133 bcse = subchk(array, hi, hshift, -hshift, scaling)
1135 bcnw = subchk(array, hi, -hshift, hshift, scaling)
1136 bcne = subchk(array, hi, hshift, hshift, scaling)
1139 call chk_sum_msg(
"v-point:", bc0, bcsw, bcse, bcnw, bcne, mesg, iounit)
1142 bcs = subchk(array, hi, 0, -hshift-1, scaling)
1144 bcs = subchk(array, hi, 0, -hshift, scaling)
1146 bce = subchk(array, hi, hshift, 0, scaling)
1147 bcw = subchk(array, hi, -hshift, 0, scaling)
1148 bcn = subchk(array, hi, 0, hshift, scaling)
1151 call chk_sum_msg_nsew(
"v-point:", bc0, bcn, bcs, bce, bcw, mesg, iounit)
1156 integer function subchk(array, HI, di, dj, scale)
1157 type(hor_index_type),
intent(in) :: HI
1158 real,
dimension(HI%isd:,HI%JsdB:),
intent(in) :: array
1159 integer,
intent(in) :: di
1160 integer,
intent(in) :: dj
1161 real,
intent(in) :: scale
1165 do j=hi%jsc+dj,hi%jec+dj;
do i=hi%isc+di,hi%iec+di
1166 bc = bitcount(abs(scale*array(i,j)))
1167 subchk = subchk + bc
1169 call sum_across_pes(subchk)
1170 subchk=mod(subchk, bc_modulus)
1173 subroutine substats(HI, array, sym_stats, aMean, aMin, aMax)
1174 type(hor_index_type),
intent(in) :: HI
1175 real,
dimension(HI%isd:,HI%JsdB:),
intent(in) :: array
1176 logical,
intent(in) :: sym_stats
1178 real,
intent(out) :: aMean
1179 real,
intent(out) :: aMin
1180 real,
intent(out) :: aMax
1182 integer :: i, j, n, JsB
1184 jsb = hi%jsc ;
if (sym_stats) jsb = hi%jsc-1
1186 amin = array(hi%isc,hi%jsc) ; amax = amin
1187 do j=jsb,hi%JecB ;
do i=hi%isc,hi%iec
1188 amin = min(amin, array(i,j))
1189 amax = max(amax, array(i,j))
1193 n = (1 + hi%jec - hi%jsc) * (1 + hi%iec - hi%isc)
1194 call sum_across_pes(n)
1195 call min_across_pes(amin)
1196 call max_across_pes(amax)
1197 amean = amean /
real(n)
1198 end subroutine substats
1200 end subroutine chksum_v_2d
1203 subroutine chksum_h_3d(array_m, mesg, HI_m, haloshift, omit_corners, scale, logunit)
1204 type(hor_index_type),
target,
intent(in) :: HI_m
1205 real,
dimension(HI_m%isd:,HI_m%jsd:,:),
target,
intent(in) :: array_m
1206 character(len=*),
intent(in) :: mesg
1207 integer,
optional,
intent(in) :: haloshift
1208 logical,
optional,
intent(in) :: omit_corners
1209 real,
optional,
intent(in) :: scale
1210 integer,
optional,
intent(in) :: logunit
1212 real,
pointer :: array(:,:,:)
1213 real,
allocatable,
dimension(:,:,:) :: rescaled_array
1214 type(hor_index_type),
pointer :: HI
1218 real :: aMean, aMin, aMax
1219 integer :: bc0, bcSW, bcSE, bcNW, bcNE, hshift
1220 integer :: bcN, bcS, bcE, bcW
1221 logical :: do_corners
1226 if (modulo(turns, 4) /= 0)
then 1228 call rotate_hor_index(hi_m, -turns, hi)
1229 allocate(array(hi%isd:hi%ied, hi%jsd:hi%jed,
size(array_m, 3)))
1236 if (checkfornans)
then 1237 if (
is_nan(array(hi%isc:hi%iec,hi%jsc:hi%jec,:))) &
1238 call chksum_error(fatal,
'NaN detected: '//trim(mesg))
1243 scaling = 1.0 ;
if (
present(scale)) scaling = scale
1244 iounit = error_unit;
if(
present(logunit)) iounit = logunit
1246 if (calculatestatistics)
then 1247 if (
present(scale))
then 1248 allocate( rescaled_array(lbound(array,1):ubound(array,1), &
1249 lbound(array,2):ubound(array,2), &
1250 lbound(array,3):ubound(array,3)) )
1251 rescaled_array(:,:,:) = 0.0
1252 do k=1,
size(array,3) ;
do j=hi%jsc,hi%jec ;
do i=hi%isc,hi%iec
1253 rescaled_array(i,j,k) = scale*array(i,j,k)
1254 enddo ;
enddo ;
enddo 1256 call substats(hi, rescaled_array, amean, amin, amax)
1257 deallocate(rescaled_array)
1259 call substats(hi, array, amean, amin, amax)
1263 call chk_sum_msg(
"h-point:", amean, amin, amax, mesg, iounit)
1266 if (.not.writechksums)
return 1268 hshift = default_shift
1269 if (
present(haloshift)) hshift = haloshift
1270 if (hshift<0) hshift = hi%ied-hi%iec
1272 if ( hi%isc-hshift<hi%isd .or. hi%iec+hshift>hi%ied .or. &
1273 hi%jsc-hshift<hi%jsd .or. hi%jec+hshift>hi%jed )
then 1274 write(0,*)
'chksum_h_3d: haloshift =',hshift
1275 write(0,*)
'chksum_h_3d: isd,isc,iec,ied=',hi%isd,hi%isc,hi%iec,hi%ied
1276 write(0,*)
'chksum_h_3d: jsd,jsc,jec,jed=',hi%jsd,hi%jsc,hi%jec,hi%jed
1277 call chksum_error(fatal,
'Error in chksum_h_3d '//trim(mesg))
1280 bc0 = subchk(array, hi, 0, 0, scaling)
1283 if (is_root_pe())
call chk_sum_msg(
"h-point:", bc0, mesg, iounit)
1287 do_corners = .true. ;
if (
present(omit_corners)) do_corners = .not.omit_corners
1289 if (do_corners)
then 1290 bcsw = subchk(array, hi, -hshift, -hshift, scaling)
1291 bcse = subchk(array, hi, hshift, -hshift, scaling)
1292 bcnw = subchk(array, hi, -hshift, hshift, scaling)
1293 bcne = subchk(array, hi, hshift, hshift, scaling)
1296 call chk_sum_msg(
"h-point:", bc0, bcsw, bcse, bcnw, bcne, mesg, iounit)
1298 bcs = subchk(array, hi, 0, -hshift, scaling)
1299 bce = subchk(array, hi, hshift, 0, scaling)
1300 bcw = subchk(array, hi, -hshift, 0, scaling)
1301 bcn = subchk(array, hi, 0, hshift, scaling)
1304 call chk_sum_msg_nsew(
"h-point:", bc0, bcn, bcs, bce, bcw, mesg, iounit)
1309 integer function subchk(array, HI, di, dj, scale)
1310 type(hor_index_type),
intent(in) :: HI
1311 real,
dimension(HI%isd:,HI%jsd:,:),
intent(in) :: array
1312 integer,
intent(in) :: di
1313 integer,
intent(in) :: dj
1314 real,
intent(in) :: scale
1315 integer :: i, j, k, bc
1317 do k=lbound(array,3),ubound(array,3) ;
do j=hi%jsc+dj,hi%jec+dj ;
do i=hi%isc+di,hi%iec+di
1318 bc = bitcount(abs(scale*array(i,j,k)))
1319 subchk = subchk + bc
1320 enddo ;
enddo ;
enddo 1321 call sum_across_pes(subchk)
1322 subchk=mod(subchk, bc_modulus)
1325 subroutine substats(HI, array, aMean, aMin, aMax)
1326 type(hor_index_type),
intent(in) :: HI
1327 real,
dimension(HI%isd:,HI%jsd:,:),
intent(in) :: array
1328 real,
intent(out) :: aMean
1329 real,
intent(out) :: aMin
1330 real,
intent(out) :: aMax
1332 integer :: i, j, k, n
1334 amin = array(hi%isc,hi%jsc,1)
1335 amax = array(hi%isc,hi%jsc,1)
1337 do k=lbound(array,3),ubound(array,3) ;
do j=hi%jsc,hi%jec ;
do i=hi%isc,hi%iec
1338 amin = min(amin, array(i,j,k))
1339 amax = max(amax, array(i,j,k))
1341 enddo ;
enddo ;
enddo 1343 call sum_across_pes(n)
1344 call min_across_pes(amin)
1345 call max_across_pes(amax)
1346 amean = amean /
real(n)
1347 end subroutine substats
1349 end subroutine chksum_h_3d
1352 subroutine chksum_b_3d(array_m, mesg, HI_m, haloshift, symmetric, omit_corners, &
1354 type(hor_index_type),
target,
intent(in) :: HI_m
1355 real,
dimension(HI_m%IsdB:,HI_m%JsdB:,:),
target,
intent(in) :: array_m
1356 character(len=*),
intent(in) :: mesg
1357 integer,
optional,
intent(in) :: haloshift
1358 logical,
optional,
intent(in) :: symmetric
1360 logical,
optional,
intent(in) :: omit_corners
1361 real,
optional,
intent(in) :: scale
1362 integer,
optional,
intent(in) :: logunit
1364 real,
pointer :: array(:,:,:)
1365 real,
allocatable,
dimension(:,:,:) :: rescaled_array
1366 type(hor_index_type),
pointer :: HI
1369 integer :: i, j, k, Is, Js
1370 real :: aMean, aMin, aMax
1371 integer :: bc0, bcSW, bcSE, bcNW, bcNE, hshift
1372 integer :: bcN, bcS, bcE, bcW
1373 logical :: do_corners, sym, sym_stats
1378 if (modulo(turns, 4) /= 0)
then 1380 call rotate_hor_index(hi_m, -turns, hi)
1381 allocate(array(hi%IsdB:hi%IedB, hi%JsdB:hi%JedB,
size(array_m, 3)))
1388 if (checkfornans)
then 1389 if (
is_nan(array(hi%IscB:hi%IecB,hi%JscB:hi%JecB,:))) &
1390 call chksum_error(fatal,
'NaN detected: '//trim(mesg))
1395 scaling = 1.0 ;
if (
present(scale)) scaling = scale
1396 iounit = error_unit;
if(
present(logunit)) iounit = logunit
1397 sym_stats = .false. ;
if (
present(symmetric)) sym_stats = symmetric
1398 if (
present(haloshift))
then ;
if (haloshift > 0) sym_stats = .true. ;
endif 1400 if (calculatestatistics)
then 1401 if (
present(scale))
then 1402 allocate( rescaled_array(lbound(array,1):ubound(array,1), &
1403 lbound(array,2):ubound(array,2), &
1404 lbound(array,3):ubound(array,3)) )
1405 rescaled_array(:,:,:) = 0.0
1406 is = hi%isc ;
if (sym_stats) is = hi%isc-1
1407 js = hi%jsc ;
if (sym_stats) js = hi%jsc-1
1408 do k=1,
size(array,3) ;
do j=js,hi%JecB ;
do i=is,hi%IecB
1409 rescaled_array(i,j,k) = scale*array(i,j,k)
1410 enddo ;
enddo ;
enddo 1411 call substats(hi, rescaled_array, sym_stats, amean, amin, amax)
1412 deallocate(rescaled_array)
1414 call substats(hi, array, sym_stats, amean, amin, amax)
1418 call chk_sum_msg(
"B-point:", amean, amin, amax, mesg, iounit)
1421 if (.not.writechksums)
return 1423 hshift = default_shift
1424 if (
present(haloshift)) hshift = haloshift
1425 if (hshift<0) hshift = hi%ied-hi%iec
1427 if ( hi%isc-hshift<hi%isd .or. hi%iec+hshift>hi%ied .or. &
1428 hi%jsc-hshift<hi%jsd .or. hi%jec+hshift>hi%jed )
then 1429 write(0,*)
'chksum_B_3d: haloshift =',hshift
1430 write(0,*)
'chksum_B_3d: isd,isc,iec,ied=',hi%isd,hi%isc,hi%iec,hi%ied
1431 write(0,*)
'chksum_B_3d: jsd,jsc,jec,jed=',hi%jsd,hi%jsc,hi%jec,hi%jed
1432 call chksum_error(fatal,
'Error in chksum_B_3d '//trim(mesg))
1435 bc0 = subchk(array, hi, 0, 0, scaling)
1437 sym = .false. ;
if (
present(symmetric)) sym = symmetric
1439 if ((hshift==0) .and. .not.sym)
then 1440 if (is_root_pe())
call chk_sum_msg(
"B-point:", bc0, mesg, iounit)
1444 do_corners = .true. ;
if (
present(omit_corners)) do_corners = .not.omit_corners
1446 if (do_corners)
then 1448 bcsw = subchk(array, hi, -hshift-1, -hshift-1, scaling)
1449 bcse = subchk(array, hi, hshift, -hshift-1, scaling)
1450 bcnw = subchk(array, hi, -hshift-1, hshift, scaling)
1452 bcsw = subchk(array, hi, -hshift-1, -hshift-1, scaling)
1453 bcse = subchk(array, hi, hshift, -hshift-1, scaling)
1454 bcnw = subchk(array, hi, -hshift-1, hshift, scaling)
1456 bcne = subchk(array, hi, hshift, hshift, scaling)
1459 call chk_sum_msg(
"B-point:", bc0, bcsw, bcse, bcnw, bcne, mesg, iounit)
1462 bcs = subchk(array, hi, 0, -hshift-1, scaling)
1463 bcw = subchk(array, hi, -hshift-1, 0, scaling)
1465 bcs = subchk(array, hi, 0, -hshift, scaling)
1466 bcw = subchk(array, hi, -hshift, 0, scaling)
1468 bce = subchk(array, hi, hshift, 0, scaling)
1469 bcn = subchk(array, hi, 0, hshift, scaling)
1472 call chk_sum_msg_nsew(
"B-point:", bc0, bcn, bcs, bce, bcw, mesg, iounit)
1477 integer function subchk(array, HI, di, dj, scale)
1478 type(hor_index_type),
intent(in) :: HI
1479 real,
dimension(HI%IsdB:,HI%JsdB:,:),
intent(in) :: array
1480 integer,
intent(in) :: di
1481 integer,
intent(in) :: dj
1482 real,
intent(in) :: scale
1483 integer :: i, j, k, bc
1486 do k=lbound(array,3),ubound(array,3) ;
do j=hi%jsc+dj,hi%jec+dj ;
do i=hi%isc+di,hi%iec+di
1487 bc = bitcount(abs(scale*array(i,j,k)))
1488 subchk = subchk + bc
1489 enddo ;
enddo ;
enddo 1490 call sum_across_pes(subchk)
1491 subchk=mod(subchk, bc_modulus)
1494 subroutine substats(HI, array, sym_stats, aMean, aMin, aMax)
1495 type(hor_index_type),
intent(in) :: HI
1496 real,
dimension(HI%IsdB:,HI%JsdB:,:),
intent(in) :: array
1497 logical,
intent(in) :: sym_stats
1499 real,
intent(out) :: aMean
1500 real,
intent(out) :: aMin
1501 real,
intent(out) :: aMax
1503 integer :: i, j, k, n, IsB, JsB
1505 isb = hi%isc ;
if (sym_stats) isb = hi%isc-1
1506 jsb = hi%jsc ;
if (sym_stats) jsb = hi%jsc-1
1508 amin = array(hi%isc,hi%jsc,1) ; amax = amin
1509 do k=lbound(array,3),ubound(array,3) ;
do j=jsb,hi%JecB ;
do i=isb,hi%IecB
1510 amin = min(amin, array(i,j,k))
1511 amax = max(amax, array(i,j,k))
1512 enddo ;
enddo ;
enddo 1514 n = (1 + hi%jec - hi%jsc) * (1 + hi%iec - hi%isc) *
size(array,3)
1515 call sum_across_pes(n)
1516 call min_across_pes(amin)
1517 call max_across_pes(amax)
1518 amean = amean /
real(n)
1519 end subroutine substats
1521 end subroutine chksum_b_3d
1524 subroutine chksum_u_3d(array_m, mesg, HI_m, haloshift, symmetric, omit_corners, &
1526 type(hor_index_type),
target,
intent(in) :: HI_m
1527 real,
dimension(HI_m%isdB:,HI_m%Jsd:,:),
target,
intent(in) :: array_m
1528 character(len=*),
intent(in) :: mesg
1529 integer,
optional,
intent(in) :: haloshift
1530 logical,
optional,
intent(in) :: symmetric
1532 logical,
optional,
intent(in) :: omit_corners
1533 real,
optional,
intent(in) :: scale
1534 integer,
optional,
intent(in) :: logunit
1536 real,
pointer :: array(:,:,:)
1537 real,
allocatable,
dimension(:,:,:) :: rescaled_array
1538 type(hor_index_type),
pointer :: HI
1541 integer :: i, j, k, Is
1542 real :: aMean, aMin, aMax
1543 integer :: bc0, bcSW, bcSE, bcNW, bcNE, hshift
1544 integer :: bcN, bcS, bcE, bcW
1545 logical :: do_corners, sym, sym_stats
1550 if (modulo(turns, 4) /= 0)
then 1552 call rotate_hor_index(hi_m, -turns, hi)
1553 if (modulo(turns, 2) /= 0)
then 1555 allocate(array(hi%isd:hi%ied, hi%JsdB:hi%JedB,
size(array_m, 3)))
1557 call vchksum(array, mesg, hi, haloshift, symmetric, omit_corners, scale, logunit)
1560 allocate(array(hi%IsdB:hi%IedB, hi%jsd:hi%jed,
size(array_m, 3)))
1568 if (checkfornans)
then 1569 if (
is_nan(array(hi%IscB:hi%IecB,hi%jsc:hi%jec,:))) &
1570 call chksum_error(fatal,
'NaN detected: '//trim(mesg))
1575 scaling = 1.0 ;
if (
present(scale)) scaling = scale
1576 iounit = error_unit;
if(
present(logunit)) iounit = logunit
1577 sym_stats = .false. ;
if (
present(symmetric)) sym_stats = symmetric
1578 if (
present(haloshift))
then ;
if (haloshift > 0) sym_stats = .true. ;
endif 1580 if (calculatestatistics)
then 1581 if (
present(scale))
then 1582 allocate( rescaled_array(lbound(array,1):ubound(array,1), &
1583 lbound(array,2):ubound(array,2), &
1584 lbound(array,3):ubound(array,3)) )
1585 rescaled_array(:,:,:) = 0.0
1586 is = hi%isc ;
if (sym_stats) is = hi%isc-1
1587 do k=1,
size(array,3) ;
do j=hi%jsc,hi%jec ;
do i=is,hi%IecB
1588 rescaled_array(i,j,k) = scale*array(i,j,k)
1589 enddo ;
enddo ;
enddo 1590 call substats(hi, rescaled_array, sym_stats, amean, amin, amax)
1591 deallocate(rescaled_array)
1593 call substats(hi, array, sym_stats, amean, amin, amax)
1596 call chk_sum_msg(
"u-point:", amean, amin, amax, mesg, iounit)
1599 if (.not.writechksums)
return 1601 hshift = default_shift
1602 if (
present(haloshift)) hshift = haloshift
1603 if (hshift<0) hshift = hi%ied-hi%iec
1605 if ( hi%isc-hshift<hi%isd .or. hi%iec+hshift>hi%ied .or. &
1606 hi%jsc-hshift<hi%jsd .or. hi%jec+hshift>hi%jed )
then 1607 write(0,*)
'chksum_u_3d: haloshift =',hshift
1608 write(0,*)
'chksum_u_3d: isd,isc,iec,ied=',hi%isd,hi%isc,hi%iec,hi%ied
1609 write(0,*)
'chksum_u_3d: jsd,jsc,jec,jed=',hi%jsd,hi%jsc,hi%jec,hi%jed
1610 call chksum_error(fatal,
'Error in chksum_u_3d '//trim(mesg))
1613 bc0 = subchk(array, hi, 0, 0, scaling)
1615 sym = .false. ;
if (
present(symmetric)) sym = symmetric
1617 if ((hshift==0) .and. .not.sym)
then 1618 if (is_root_pe())
call chk_sum_msg(
"u-point:", bc0, mesg, iounit)
1622 do_corners = .true. ;
if (
present(omit_corners)) do_corners = .not.omit_corners
1625 bcw = subchk(array, hi, -hshift-1, 0, scaling)
1626 if (is_root_pe())
call chk_sum_msg_w(
"u-point:", bc0, bcw, mesg, iounit)
1627 elseif (do_corners)
then 1629 bcsw = subchk(array, hi, -hshift-1, -hshift, scaling)
1630 bcnw = subchk(array, hi, -hshift-1, hshift, scaling)
1632 bcsw = subchk(array, hi, -hshift, -hshift, scaling)
1633 bcnw = subchk(array, hi, -hshift, hshift, scaling)
1635 bcse = subchk(array, hi, hshift, -hshift, scaling)
1636 bcne = subchk(array, hi, hshift, hshift, scaling)
1639 call chk_sum_msg(
"u-point:", bc0, bcsw, bcse, bcnw, bcne, mesg, iounit)
1641 bcs = subchk(array, hi, 0, -hshift, scaling)
1642 bce = subchk(array, hi, hshift, 0, scaling)
1644 bcw = subchk(array, hi, -hshift-1, 0, scaling)
1646 bcw = subchk(array, hi, -hshift, 0, scaling)
1648 bcn = subchk(array, hi, 0, hshift, scaling)
1651 call chk_sum_msg_nsew(
"u-point:", bc0, bcn, bcs, bce, bcw, mesg, iounit)
1656 integer function subchk(array, HI, di, dj, scale)
1657 type(hor_index_type),
intent(in) :: HI
1658 real,
dimension(HI%IsdB:,HI%jsd:,:),
intent(in) :: array
1659 integer,
intent(in) :: di
1660 integer,
intent(in) :: dj
1661 real,
intent(in) :: scale
1662 integer :: i, j, k, bc
1665 do k=lbound(array,3),ubound(array,3) ;
do j=hi%jsc+dj,hi%jec+dj ;
do i=hi%isc+di,hi%iec+di
1666 bc = bitcount(abs(scale*array(i,j,k)))
1667 subchk = subchk + bc
1668 enddo ;
enddo ;
enddo 1669 call sum_across_pes(subchk)
1670 subchk=mod(subchk, bc_modulus)
1673 subroutine substats(HI, array, sym_stats, aMean, aMin, aMax)
1674 type(hor_index_type),
intent(in) :: HI
1675 real,
dimension(HI%IsdB:,HI%jsd:,:),
intent(in) :: array
1676 logical,
intent(in) :: sym_stats
1678 real,
intent(out) :: aMean
1679 real,
intent(out) :: aMin
1680 real,
intent(out) :: aMax
1682 integer :: i, j, k, n, IsB
1684 isb = hi%isc ;
if (sym_stats) isb = hi%isc-1
1686 amin = array(hi%isc,hi%jsc,1) ; amax = amin
1687 do k=lbound(array,3),ubound(array,3) ;
do j=hi%jsc,hi%jec ;
do i=isb,hi%IecB
1688 amin = min(amin, array(i,j,k))
1689 amax = max(amax, array(i,j,k))
1690 enddo ;
enddo ;
enddo 1693 n = (1 + hi%jec - hi%jsc) * (1 + hi%iec - hi%isc) *
size(array,3)
1694 call sum_across_pes(n)
1695 call min_across_pes(amin)
1696 call max_across_pes(amax)
1697 amean = amean /
real(n)
1698 end subroutine substats
1700 end subroutine chksum_u_3d
1703 subroutine chksum_v_3d(array_m, mesg, HI_m, haloshift, symmetric, omit_corners, &
1705 type(hor_index_type),
target,
intent(in) :: HI_m
1706 real,
dimension(HI_m%isd:,HI_m%JsdB:,:),
target,
intent(in) :: array_m
1707 character(len=*),
intent(in) :: mesg
1708 integer,
optional,
intent(in) :: haloshift
1709 logical,
optional,
intent(in) :: symmetric
1711 logical,
optional,
intent(in) :: omit_corners
1712 real,
optional,
intent(in) :: scale
1713 integer,
optional,
intent(in) :: logunit
1715 real,
pointer :: array(:,:,:)
1716 real,
allocatable,
dimension(:,:,:) :: rescaled_array
1717 type(hor_index_type),
pointer :: HI
1720 integer :: i, j, k, Js
1721 integer :: bc0, bcSW, bcSE, bcNW, bcNE, hshift
1722 integer :: bcN, bcS, bcE, bcW
1723 real :: aMean, aMin, aMax
1724 logical :: do_corners, sym, sym_stats
1729 if (modulo(turns, 4) /= 0)
then 1731 call rotate_hor_index(hi_m, -turns, hi)
1732 if (modulo(turns, 2) /= 0)
then 1734 allocate(array(hi%IsdB:hi%IedB, hi%jsd:hi%jed,
size(array_m, 3)))
1736 call uchksum(array, mesg, hi, haloshift, symmetric, omit_corners, scale, logunit)
1739 allocate(array(hi%isd:hi%ied, hi%JsdB:hi%JedB,
size(array_m, 3)))
1747 if (checkfornans)
then 1748 if (
is_nan(array(hi%isc:hi%iec,hi%JscB:hi%JecB,:))) &
1749 call chksum_error(fatal,
'NaN detected: '//trim(mesg))
1754 scaling = 1.0 ;
if (
present(scale)) scaling = scale
1755 iounit = error_unit;
if(
present(logunit)) iounit = logunit
1756 sym_stats = .false. ;
if (
present(symmetric)) sym_stats = symmetric
1757 if (
present(haloshift))
then ;
if (haloshift > 0) sym_stats = .true. ;
endif 1759 if (calculatestatistics)
then 1760 if (
present(scale))
then 1761 allocate( rescaled_array(lbound(array,1):ubound(array,1), &
1762 lbound(array,2):ubound(array,2), &
1763 lbound(array,3):ubound(array,3)) )
1764 rescaled_array(:,:,:) = 0.0
1765 js = hi%jsc ;
if (sym_stats) js = hi%jsc-1
1766 do k=1,
size(array,3) ;
do j=js,hi%JecB ;
do i=hi%isc,hi%iec
1767 rescaled_array(i,j,k) = scale*array(i,j,k)
1768 enddo ;
enddo ;
enddo 1769 call substats(hi, rescaled_array, sym_stats, amean, amin, amax)
1770 deallocate(rescaled_array)
1772 call substats(hi, array, sym_stats, amean, amin, amax)
1775 call chk_sum_msg(
"v-point:", amean, amin, amax, mesg, iounit)
1778 if (.not.writechksums)
return 1780 hshift = default_shift
1781 if (
present(haloshift)) hshift = haloshift
1782 if (hshift<0) hshift = hi%ied-hi%iec
1784 if ( hi%isc-hshift<hi%isd .or. hi%iec+hshift>hi%ied .or. &
1785 hi%jsc-hshift<hi%jsd .or. hi%jec+hshift>hi%jed )
then 1786 write(0,*)
'chksum_v_3d: haloshift =',hshift
1787 write(0,*)
'chksum_v_3d: isd,isc,iec,ied=',hi%isd,hi%isc,hi%iec,hi%ied
1788 write(0,*)
'chksum_v_3d: jsd,jsc,jec,jed=',hi%jsd,hi%jsc,hi%jec,hi%jed
1789 call chksum_error(fatal,
'Error in chksum_v_3d '//trim(mesg))
1792 bc0 = subchk(array, hi, 0, 0, scaling)
1794 sym = .false. ;
if (
present(symmetric)) sym = symmetric
1796 if ((hshift==0) .and. .not.sym)
then 1797 if (is_root_pe())
call chk_sum_msg(
"v-point:", bc0, mesg, iounit)
1801 do_corners = .true. ;
if (
present(omit_corners)) do_corners = .not.omit_corners
1804 bcs = subchk(array, hi, 0, -hshift-1, scaling)
1805 if (is_root_pe())
call chk_sum_msg_s(
"v-point:", bc0, bcs, mesg, iounit)
1806 elseif (do_corners)
then 1808 bcsw = subchk(array, hi, -hshift, -hshift-1, scaling)
1809 bcse = subchk(array, hi, hshift, -hshift-1, scaling)
1811 bcsw = subchk(array, hi, -hshift, -hshift, scaling)
1812 bcse = subchk(array, hi, hshift, -hshift, scaling)
1814 bcnw = subchk(array, hi, -hshift, hshift, scaling)
1815 bcne = subchk(array, hi, hshift, hshift, scaling)
1818 call chk_sum_msg(
"v-point:", bc0, bcsw, bcse, bcnw, bcne, mesg, iounit)
1821 bcs = subchk(array, hi, 0, -hshift-1, scaling)
1823 bcs = subchk(array, hi, 0, -hshift, scaling)
1825 bce = subchk(array, hi, hshift, 0, scaling)
1826 bcw = subchk(array, hi, -hshift, 0, scaling)
1827 bcn = subchk(array, hi, 0, hshift, scaling)
1830 call chk_sum_msg_nsew(
"v-point:", bc0, bcn, bcs, bce, bcw, mesg, iounit)
1835 integer function subchk(array, HI, di, dj, scale)
1836 type(hor_index_type),
intent(in) :: HI
1837 real,
dimension(HI%isd:,HI%JsdB:,:),
intent(in) :: array
1838 integer,
intent(in) :: di
1839 integer,
intent(in) :: dj
1840 real,
intent(in) :: scale
1841 integer :: i, j, k, bc
1844 do k=lbound(array,3),ubound(array,3) ;
do j=hi%jsc+dj,hi%jec+dj ;
do i=hi%isc+di,hi%iec+di
1845 bc = bitcount(abs(scale*array(i,j,k)))
1846 subchk = subchk + bc
1847 enddo ;
enddo ;
enddo 1848 call sum_across_pes(subchk)
1849 subchk=mod(subchk, bc_modulus)
1853 subroutine substats(HI, array, sym_stats, aMean, aMin, aMax)
1854 type(hor_index_type),
intent(in) :: HI
1855 real,
dimension(HI%isd:,HI%JsdB:,:),
intent(in) :: array
1856 logical,
intent(in) :: sym_stats
1858 real,
intent(out) :: aMean
1859 real,
intent(out) :: aMin
1860 real,
intent(out) :: aMax
1862 integer :: i, j, k, n, JsB
1864 jsb = hi%jsc ;
if (sym_stats) jsb = hi%jsc-1
1866 amin = array(hi%isc,hi%jsc,1) ; amax = amin
1867 do k=lbound(array,3),ubound(array,3) ;
do j=jsb,hi%JecB ;
do i=hi%isc,hi%iec
1868 amin = min(amin, array(i,j,k))
1869 amax = max(amax, array(i,j,k))
1870 enddo ;
enddo ;
enddo 1873 n = (1 + hi%jec - hi%jsc) * (1 + hi%iec - hi%isc) *
size(array,3)
1874 call sum_across_pes(n)
1875 call min_across_pes(amin)
1876 call max_across_pes(amax)
1877 amean = amean /
real(n)
1878 end subroutine substats
1880 end subroutine chksum_v_3d
1886 subroutine chksum1d(array, mesg, start_i, end_i, compare_PEs)
1887 real,
dimension(:),
intent(in) :: array
1888 character(len=*),
intent(in) :: mesg
1889 integer,
optional,
intent(in) :: start_i
1890 integer,
optional,
intent(in) :: end_i
1891 logical,
optional,
intent(in) :: compare_PEs
1894 integer :: is, ie, i, bc, sum1, sum_bc
1896 real,
allocatable :: sum_here(:)
1901 is = lbound(array,1) ; ie = ubound(array,1)
1902 if (
present(start_i)) is = start_i
1903 if (
present(end_i)) ie = end_i
1904 compare = .true. ;
if (
present(compare_pes)) compare = compare_pes
1906 sum = 0.0 ; sum_bc = 0
1908 sum = sum + array(i)
1909 bc = bitcount(abs(array(i)))
1910 sum_bc = sum_bc + bc
1913 pe_num = pe_here() + 1 - root_pe() ; npes = num_pes()
1914 allocate(sum_here(npes)) ; sum_here(:) = 0.0 ; sum_here(pe_num) = sum
1915 call sum_across_pes(sum_here,npes)
1918 call sum_across_pes(sum1)
1920 if (.not.compare)
then 1922 do i=1,npes ; sum = sum + sum_here(i) ;
enddo 1924 elseif (is_root_pe())
then 1925 if (sum1 /= npes*sum_bc) &
1926 write(0,
'(A40," bitcounts do not match across PEs: ",I12,1X,I12)') &
1927 mesg, sum1, npes*sum_bc
1928 do i=1,npes ;
if (sum /= sum_here(i))
then 1929 write(0,
'(A40," PE ",i4," sum mismatches root_PE: ",3(ES22.13,1X))') &
1930 mesg, i, sum_here(i), sum, sum_here(i)-sum
1933 deallocate(sum_here)
1936 write(0,
'(A50,1X,ES25.16,1X,I12)') mesg, sum, sum_bc
1938 end subroutine chksum1d
1944 subroutine chksum2d(array, mesg)
1946 real,
dimension(:,:) :: array
1947 character(len=*) :: mesg
1949 integer :: xs,xe,ys,ye,i,j,sum1,bc
1952 xs = lbound(array,1) ; xe = ubound(array,1)
1953 ys = lbound(array,2) ; ye = ubound(array,2)
1955 sum = 0.0 ; sum1 = 0
1956 do i=xs,xe ;
do j=ys,ye
1957 bc = bitcount(abs(array(i,j)))
1960 call sum_across_pes(sum1)
1965 write(0,
'(A50,1X,ES25.16,1X,I12)') mesg, sum, sum1
1969 end subroutine chksum2d
1972 subroutine chksum3d(array, mesg)
1974 real,
dimension(:,:,:) :: array
1975 character(len=*) :: mesg
1977 integer :: xs,xe,ys,ye,zs,ze,i,j,k, bc,sum1
1980 xs = lbound(array,1) ; xe = ubound(array,1)
1981 ys = lbound(array,2) ; ye = ubound(array,2)
1982 zs = lbound(array,3) ; ze = ubound(array,3)
1984 sum = 0.0 ; sum1 = 0
1985 do i=xs,xe ;
do j=ys,ye ;
do k=zs,ze
1986 bc = bitcount(abs(array(i,j,k)))
1988 enddo ;
enddo ;
enddo 1990 call sum_across_pes(sum1)
1994 write(0,
'(A50,1X,ES25.16,1X,I12)') mesg, sum, sum1
1998 end subroutine chksum3d
2001 function is_nan_0d(x)
2002 real,
intent(in) :: x
2003 logical :: is_nan_0d
2007 if (((x < 0.0) .and. (x >= 0.0)) .or. &
2008 (.not.(x < 0.0) .and. .not.(x >= 0.0)))
then 2014 end function is_nan_0d
2017 function is_nan_1d(x, skip_mpp)
2018 real,
dimension(:),
intent(in) :: x
2019 logical,
optional,
intent(in) :: skip_mpp
2021 logical :: is_nan_1d
2027 do i = lbound(x,1), ubound(x,1)
2028 if (is_nan_0d(x(i))) n = n + 1
2031 if (
present(skip_mpp)) call_mpp = .not.skip_mpp
2033 if (call_mpp)
call sum_across_pes(n)
2035 if (n>0) is_nan_1d = .true.
2037 end function is_nan_1d
2040 function is_nan_2d(x)
2041 real,
dimension(:,:),
intent(in) :: x
2042 logical :: is_nan_2d
2047 do j = lbound(x,2), ubound(x,2) ;
do i = lbound(x,1), ubound(x,1)
2048 if (is_nan_0d(x(i,j))) n = n + 1
2050 call sum_across_pes(n)
2052 if (n>0) is_nan_2d = .true.
2054 end function is_nan_2d
2057 function is_nan_3d(x)
2058 real,
dimension(:,:,:),
intent(in) :: x
2059 logical :: is_nan_3d
2061 integer :: i, j, k, n
2064 do k = lbound(x,3), ubound(x,3)
2065 do j = lbound(x,2), ubound(x,2) ;
do i = lbound(x,1), ubound(x,1)
2066 if (is_nan_0d(x(i,j,k))) n = n + 1
2069 call sum_across_pes(n)
2071 if (n>0) is_nan_3d = .true.
2073 end function is_nan_3d
2076 subroutine chk_sum_msg1(fmsg, bc0, mesg, iounit)
2077 character(len=*),
intent(in) :: fmsg
2078 character(len=*),
intent(in) :: mesg
2079 integer,
intent(in) :: bc0
2080 integer,
intent(in) :: iounit
2083 write(iounit,
'(A,1(A,I10,X),A)') fmsg,
" c=", bc0, trim(mesg)
2084 end subroutine chk_sum_msg1
2087 subroutine chk_sum_msg5(fmsg, bc0, bcSW, bcSE, bcNW, bcNE, mesg, iounit)
2088 character(len=*),
intent(in) :: fmsg
2089 character(len=*),
intent(in) :: mesg
2090 integer,
intent(in) :: bc0
2091 integer,
intent(in) :: bcSW
2092 integer,
intent(in) :: bcSE
2093 integer,
intent(in) :: bcNW
2094 integer,
intent(in) :: bcNE
2095 integer,
intent(in) :: iounit
2097 if (is_root_pe())
write(iounit,
'(A,5(A,I10,1X),A)') &
2098 fmsg,
" c=", bc0,
"sw=", bcsw,
"se=", bcse,
"nw=", bcnw,
"ne=", bcne, trim(mesg)
2099 end subroutine chk_sum_msg5
2102 subroutine chk_sum_msg_nsew(fmsg, bc0, bcN, bcS, bcE, bcW, mesg, iounit)
2103 character(len=*),
intent(in) :: fmsg
2104 character(len=*),
intent(in) :: mesg
2105 integer,
intent(in) :: bc0
2106 integer,
intent(in) :: bcN
2107 integer,
intent(in) :: bcS
2108 integer,
intent(in) :: bcE
2109 integer,
intent(in) :: bcW
2110 integer,
intent(in) :: iounit
2112 if (is_root_pe())
write(iounit,
'(A,5(A,I10,1X),A)') &
2113 fmsg,
" c=", bc0,
"N=", bcn,
"S=", bcs,
"E=", bce,
"W=", bcw, trim(mesg)
2114 end subroutine chk_sum_msg_nsew
2117 subroutine chk_sum_msg_s(fmsg, bc0, bcS, mesg, iounit)
2118 character(len=*),
intent(in) :: fmsg
2119 character(len=*),
intent(in) :: mesg
2120 integer,
intent(in) :: bc0
2121 integer,
intent(in) :: bcS
2122 integer,
intent(in) :: iounit
2124 if (is_root_pe())
write(iounit,
'(A,2(A,I10,1X),A)') &
2125 fmsg,
" c=", bc0,
"S=", bcs, trim(mesg)
2126 end subroutine chk_sum_msg_s
2129 subroutine chk_sum_msg_w(fmsg, bc0, bcW, mesg, iounit)
2130 character(len=*),
intent(in) :: fmsg
2131 character(len=*),
intent(in) :: mesg
2132 integer,
intent(in) :: bc0
2133 integer,
intent(in) :: bcW
2134 integer,
intent(in) :: iounit
2136 if (is_root_pe())
write(iounit,
'(A,2(A,I10,1X),A)') &
2137 fmsg,
" c=", bc0,
"W=", bcw, trim(mesg)
2138 end subroutine chk_sum_msg_w
2141 subroutine chk_sum_msg2(fmsg, bc0, bcSW, mesg, iounit)
2142 character(len=*),
intent(in) :: fmsg
2143 character(len=*),
intent(in) :: mesg
2144 integer,
intent(in) :: bc0
2145 integer,
intent(in) :: bcSW
2146 integer,
intent(in) :: iounit
2148 if (is_root_pe())
write(iounit,
'(A,2(A,I9,1X),A)') &
2149 fmsg,
" c=", bc0,
"s/w=", bcsw, trim(mesg)
2150 end subroutine chk_sum_msg2
2153 subroutine chk_sum_msg3(fmsg, aMean, aMin, aMax, mesg, iounit)
2154 character(len=*),
intent(in) :: fmsg
2155 character(len=*),
intent(in) :: mesg
2156 real,
intent(in) :: aMean
2157 real,
intent(in) :: aMin
2158 real,
intent(in) :: aMax
2159 integer,
intent(in) :: iounit
2164 if (is_root_pe())
write(iounit,
'(A,3(A,ES25.16,1X),A)') &
2165 fmsg,
" mean=", amean,
"min=", (0. + amin),
"max=", (0. + amax), trim(mesg)
2166 end subroutine chk_sum_msg3
2170 subroutine mom_checksums_init(param_file)
2173 #include "version_variable.h" 2174 character(len=40) :: mdl =
"MOM_checksums" 2178 end subroutine mom_checksums_init
2181 subroutine chksum_error(signal, message)
2183 integer,
intent(in) :: signal
2184 character(len=*),
intent(in) :: message
2185 call mom_error(signal, message)
2186 end subroutine chksum_error
2190 integer function bitcount(x)
2191 real,
intent(in) :: x
2193 integer,
parameter :: xk = kind(x)
2196 bitcount = popcnt(transfer(x, 1_xk))
2197 end function bitcount
Checksums an array (2d or 3d) staggered at C-grid u points.
A structure that can be parsed to read and document run-time parameters.
The MOM6 facility to parse input files for runtime parameters.
Defines the horizontal index type (hor_index_type) used for providing index ranges.
Returns .true. if any element of x is a NaN, and .false. otherwise.
Checksums a pair velocity arrays (2d or 3d) staggered at C-grid locations.
Container for horizontal index ranges for data, computational and global domains. ...
Routines to calculate checksums of various array and vector types.
Interfaces to non-domain-oriented communication subroutines, including the MOM6 reproducing sums faci...
Write a message with either checksums or numerical statistics of arrays.
This is an older interface that has been renamed Bchksum.
Checksums an array (2d or 3d) staggered at tracer points.
Routines for error handling and I/O management.
Checksums a pair of arrays (2d or 3d) staggered at corner points.
An overloaded interface to log version information about modules.
This is an older interface for 1-, 2-, or 3-D checksums.
Find an accurate and order-invariant sum of a distributed 2d or 3d field.
Checksums an array (2d or 3d) staggered at corner points.
Checksums an array (2d or 3d) staggered at C-grid v points.
Checksums a pair of arrays (2d or 3d) staggered at tracer points.