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
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
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
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
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)
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
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)
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)
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
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
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
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
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, &
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
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)
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)
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
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
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
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
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, &
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
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)
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)
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, &
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
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)
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)
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)
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
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)
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)
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, &
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
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)
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)
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, &
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
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)
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)
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, &
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
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)
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)
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