MODULE array_tools !----------------------------------------------------------------------------- ! CVS:$Id: array_tools.F90,v 1.1 2001/02/16 21:19:47 klindsay Exp $ !----------------------------------------------------------------------------- USE kinds_mod USE msg_mod IMPLICIT NONE PRIVATE !----------------------------------------------------------------------------- ! public functions !----------------------------------------------------------------------------- PUBLIC :: rms, equal !----------------------------------------------------------------------------- ! generic interfaces !----------------------------------------------------------------------------- INTERFACE rms MODULE PROCEDURE & rms_1D_s, rms_1D_d, & rms_2D_s, rms_2D_d END INTERFACE INTERFACE equal MODULE PROCEDURE & equal_0D_ss, equal_0D_sd, equal_0D_ds, equal_0D_dd, & equal_1D_ss, equal_1D_sd, equal_1D_ds, equal_1D_dd, & equal_2D_ss, equal_2D_sd, equal_2D_ds, equal_2D_dd END INTERFACE !***************************************************************************** CONTAINS !***************************************************************************** REAL(KIND=real_kind) FUNCTION rms_1D_s(A, WEIGHT, MASK) !--------------------------------------------------------------------------- ! arguments !--------------------------------------------------------------------------- REAL(KIND=real_kind), DIMENSION(:), INTENT(IN) :: A REAL(KIND=real_kind), DIMENSION(:), INTENT(IN), OPTIONAL :: WEIGHT LOGICAL(KIND=log_kind), DIMENSION(:), INTENT(IN), OPTIONAL :: MASK !--------------------------------------------------------------------------- ! local variables !--------------------------------------------------------------------------- CHARACTER(LEN=*), PARAMETER :: sub_name = 'rms_1D_s' INTEGER(KIND=int_kind) :: imax, i, cnt REAL(KIND=real_kind) :: work IF (PRESENT(WEIGHT)) THEN IF (SIZE(A) /= SIZE(WEIGHT)) THEN CALL msg_write(sub_name, 'size mismatch between A & WEIGHT') END IF END IF IF (PRESENT(MASK)) THEN IF (SIZE(A) /= SIZE(MASK)) THEN CALL msg_write(sub_name, 'size mismatch between A & MASK') END IF END IF imax = SIZE(A) work = 0.0_real_kind IF (PRESENT(MASK)) THEN cnt = 0 IF (PRESENT(WEIGHT)) THEN DO i = 1,imax IF (MASK(i)) THEN work = work + WEIGHT(i) * A(i) ** 2 cnt = cnt + 1 END IF END DO ELSE DO i = 1,imax IF (MASK(i)) THEN work = work + WEIGHT(i) * A(i) ** 2 cnt = cnt + 1 END IF END DO END IF IF (cnt /= 0) work = work / REAL(cnt,real_kind) ELSE IF (PRESENT(WEIGHT)) THEN DO i = 1,imax work = work + WEIGHT(i) * A(i) ** 2 END DO ELSE DO i = 1,imax work = work + A(i) ** 2 END DO END IF IF (imax /= 0) work = work / REAL(imax,real_kind) END IF rms_1D_s = SQRT(work) END FUNCTION rms_1D_s !***************************************************************************** REAL(KIND=dbl_kind) FUNCTION rms_1D_d(A, WEIGHT, MASK) !--------------------------------------------------------------------------- ! arguments !--------------------------------------------------------------------------- REAL(KIND=dbl_kind), DIMENSION(:), INTENT(IN) :: A REAL(KIND=dbl_kind), DIMENSION(:), INTENT(IN), OPTIONAL :: WEIGHT LOGICAL(KIND=log_kind), DIMENSION(:), INTENT(IN), OPTIONAL :: MASK !--------------------------------------------------------------------------- ! local variables !--------------------------------------------------------------------------- CHARACTER(LEN=*), PARAMETER :: sub_name = 'rms_1D_d' INTEGER(KIND=int_kind) :: imax, i, cnt REAL(KIND=dbl_kind) :: work IF (PRESENT(WEIGHT)) THEN IF (SIZE(A) /= SIZE(WEIGHT)) THEN CALL msg_write(sub_name, 'size mismatch between A & WEIGHT') END IF END IF IF (PRESENT(MASK)) THEN IF (SIZE(A) /= SIZE(MASK)) THEN CALL msg_write(sub_name, 'size mismatch between A & MASK') END IF END IF imax = SIZE(A) work = 0.0_dbl_kind IF (PRESENT(MASK)) THEN cnt = 0 IF (PRESENT(WEIGHT)) THEN DO i = 1,imax IF (MASK(i)) THEN work = work + WEIGHT(i) * A(i) ** 2 cnt = cnt + 1 END IF END DO ELSE DO i = 1,imax IF (MASK(i)) THEN work = work + WEIGHT(i) * A(i) ** 2 cnt = cnt + 1 END IF END DO END IF IF (cnt /= 0) work = work / REAL(cnt,dbl_kind) ELSE IF (PRESENT(WEIGHT)) THEN DO i = 1,imax work = work + WEIGHT(i) * A(i) ** 2 END DO ELSE DO i = 1,imax work = work + A(i) ** 2 END DO END IF IF (imax /= 0) work = work / REAL(imax,dbl_kind) END IF rms_1D_d = SQRT(work) END FUNCTION rms_1D_d !***************************************************************************** REAL(KIND=real_kind) FUNCTION rms_2D_s(A, WEIGHT, MASK) !--------------------------------------------------------------------------- ! arguments !--------------------------------------------------------------------------- REAL(KIND=real_kind), DIMENSION(:,:), INTENT(IN) :: A REAL(KIND=real_kind), DIMENSION(:,:), INTENT(IN), OPTIONAL :: WEIGHT LOGICAL(KIND=log_kind), DIMENSION(:,:), INTENT(IN), OPTIONAL :: MASK !--------------------------------------------------------------------------- ! local variables !--------------------------------------------------------------------------- CHARACTER(LEN=*), PARAMETER :: sub_name = 'rms_2D_s' INTEGER(KIND=int_kind) :: imax, jmax, i, j, cnt REAL(KIND=real_kind) :: work IF (PRESENT(WEIGHT)) THEN IF (SIZE(A,1) /= SIZE(WEIGHT,1) .OR. SIZE(A,2) /= SIZE(WEIGHT,2)) THEN CALL msg_write(sub_name, 'size mismatch between A & WEIGHT') END IF END IF IF (PRESENT(MASK)) THEN IF (SIZE(A,1) /= SIZE(MASK,1) .OR. SIZE(A,2) /= SIZE(MASK,2)) THEN CALL msg_write(sub_name, 'size mismatch between A & MASK') END IF END IF imax = SIZE(A,1) jmax = SIZE(A,2) work = 0.0_real_kind IF (PRESENT(MASK)) THEN cnt = 0 IF (PRESENT(WEIGHT)) THEN DO j = 1,jmax DO i = 1,imax IF (MASK(i,j)) THEN work = work + WEIGHT(i,j) * A(i,j) ** 2 cnt = cnt + 1 END IF END DO END DO ELSE DO j = 1,jmax DO i = 1,imax IF (MASK(i,j)) THEN work = work + A(i,j) ** 2 cnt = cnt + 1 END IF END DO END DO END IF IF (cnt /= 0) work = work / REAL(cnt,real_kind) ELSE IF (PRESENT(WEIGHT)) THEN DO j = 1,jmax DO i = 1,imax work = work + WEIGHT(i,j) * A(i,j) ** 2 END DO END DO ELSE DO j = 1,jmax DO i = 1,imax work = work + A(i,j) ** 2 END DO END DO END IF IF (imax /= 0 .AND. jmax /= 0) work = work / REAL(imax*jmax,real_kind) END IF rms_2D_s = SQRT(work) END FUNCTION rms_2D_s !***************************************************************************** REAL(KIND=dbl_kind) FUNCTION rms_2D_d(A, WEIGHT, MASK) !--------------------------------------------------------------------------- ! arguments !--------------------------------------------------------------------------- REAL(KIND=dbl_kind), DIMENSION(:,:), INTENT(IN) :: A REAL(KIND=dbl_kind), DIMENSION(:,:), INTENT(IN), OPTIONAL :: WEIGHT LOGICAL(KIND=log_kind), DIMENSION(:,:), INTENT(IN), OPTIONAL :: MASK !--------------------------------------------------------------------------- ! local variables !--------------------------------------------------------------------------- CHARACTER(LEN=*), PARAMETER :: sub_name = 'rms_2D_d' INTEGER(KIND=int_kind) :: imax, jmax, i, j, cnt REAL(KIND=dbl_kind) :: work IF (PRESENT(WEIGHT)) THEN IF (SIZE(A,1) /= SIZE(WEIGHT,1) .OR. SIZE(A,2) /= SIZE(WEIGHT,2)) THEN CALL msg_write(sub_name, 'size mismatch between A & WEIGHT') END IF END IF IF (PRESENT(MASK)) THEN IF (SIZE(A,1) /= SIZE(MASK,1) .OR. SIZE(A,2) /= SIZE(MASK,2)) THEN CALL msg_write(sub_name, 'size mismatch between A & MASK') END IF END IF imax = SIZE(A,1) jmax = SIZE(A,2) work = 0.0_dbl_kind IF (PRESENT(MASK)) THEN cnt = 0 IF (PRESENT(WEIGHT)) THEN DO j = 1,jmax DO i = 1,imax IF (MASK(i,j)) THEN work = work + WEIGHT(i,j) * A(i,j) ** 2 cnt = cnt + 1 END IF END DO END DO ELSE DO j = 1,jmax DO i = 1,imax IF (MASK(i,j)) THEN work = work + A(i,j) ** 2 cnt = cnt + 1 END IF END DO END DO END IF IF (cnt /= 0) work = work / REAL(cnt,dbl_kind) ELSE IF (PRESENT(WEIGHT)) THEN DO j = 1,jmax DO i = 1,imax work = work + WEIGHT(i,j) * A(i,j) ** 2 END DO END DO ELSE DO j = 1,jmax DO i = 1,imax work = work + A(i,j) ** 2 END DO END DO END IF IF (imax /= 0 .AND. jmax /= 0) work = work / REAL(imax*jmax,dbl_kind) END IF rms_2D_d = SQRT(work) END FUNCTION rms_2D_d !***************************************************************************** LOGICAL FUNCTION equal_0D_ss(A, B, RELTOL, ABSTOL) !--------------------------------------------------------------------------- ! arguments !--------------------------------------------------------------------------- REAL(KIND=real_kind), INTENT(IN) :: A REAL(KIND=real_kind), INTENT(IN) :: B REAL(KIND=real_kind), INTENT(IN), OPTIONAL :: RELTOL, ABSTOL !--------------------------------------------------------------------------- ! local variables !--------------------------------------------------------------------------- CHARACTER(LEN=*), PARAMETER :: sub_name = 'equal_0D_ss' REAL(KIND=real_kind) :: reltol_actual, abstol_actual REAL(KIND=real_kind) :: diff, mag IF (PRESENT(RELTOL)) THEN reltol_actual = RELTOL ELSE reltol_actual = 1.0e-4_real_kind END IF IF (PRESENT(ABSTOL)) THEN abstol_actual = ABSTOL ELSE abstol_actual = 0.0_real_kind END IF equal_0D_ss = .FALSE. diff = ABS(A - B) IF (diff < abstol_actual) equal_0D_ss = .TRUE. mag = MAX(ABS(A), ABS(B)) IF (diff < mag * reltol_actual) equal_0D_ss = .TRUE. END FUNCTION equal_0D_ss !***************************************************************************** LOGICAL FUNCTION equal_0D_sd(A, B, RELTOL, ABSTOL) !--------------------------------------------------------------------------- ! arguments !--------------------------------------------------------------------------- REAL(KIND=real_kind), INTENT(IN) :: A REAL(KIND=dbl_kind), INTENT(IN) :: B REAL(KIND=real_kind), INTENT(IN), OPTIONAL :: RELTOL, ABSTOL !--------------------------------------------------------------------------- ! local variables !--------------------------------------------------------------------------- CHARACTER(LEN=*), PARAMETER :: sub_name = 'equal_0D_sd' REAL(KIND=real_kind) :: B_real B_real = REAL(B, real_kind) equal_0D_sd = equal_0D_ss(A, B_real, RELTOL, ABSTOL) END FUNCTION equal_0D_sd !***************************************************************************** LOGICAL FUNCTION equal_0D_ds(A, B, RELTOL, ABSTOL) !--------------------------------------------------------------------------- ! arguments !--------------------------------------------------------------------------- REAL(KIND=dbl_kind), INTENT(IN) :: A REAL(KIND=real_kind), INTENT(IN) :: B REAL(KIND=real_kind), INTENT(IN), OPTIONAL :: RELTOL, ABSTOL !--------------------------------------------------------------------------- ! local variables !--------------------------------------------------------------------------- CHARACTER(LEN=*), PARAMETER :: sub_name = 'equal_0D_ds' REAL(KIND=real_kind) :: A_real A_real = REAL(A, real_kind) equal_0D_ds = equal_0D_ss(A_real, B, RELTOL, ABSTOL) END FUNCTION equal_0D_ds !***************************************************************************** LOGICAL FUNCTION equal_0D_dd(A, B, RELTOL, ABSTOL) !--------------------------------------------------------------------------- ! arguments !--------------------------------------------------------------------------- REAL(KIND=dbl_kind), INTENT(IN) :: A REAL(KIND=dbl_kind), INTENT(IN) :: B REAL(KIND=dbl_kind), INTENT(IN), OPTIONAL :: RELTOL, ABSTOL !--------------------------------------------------------------------------- ! local variables !--------------------------------------------------------------------------- CHARACTER(LEN=*), PARAMETER :: sub_name = 'equal_0D_dd' REAL(KIND=dbl_kind) :: reltol_actual, abstol_actual REAL(KIND=dbl_kind) :: diff, mag IF (PRESENT(RELTOL)) THEN reltol_actual = RELTOL ELSE reltol_actual = 1.0e-8_dbl_kind END IF IF (PRESENT(ABSTOL)) THEN abstol_actual = ABSTOL ELSE abstol_actual = 0.0_dbl_kind END IF equal_0D_dd = .FALSE. diff = ABS(A - B) IF (diff < abstol_actual) equal_0D_dd = .TRUE. mag = MAX(ABS(A), ABS(B)) IF (diff < mag * reltol_actual) equal_0D_dd = .TRUE. END FUNCTION equal_0D_dd !***************************************************************************** LOGICAL FUNCTION equal_1D_ss(A, B, WEIGHT, MASK, RELTOL, ABSTOL) !--------------------------------------------------------------------------- ! arguments !--------------------------------------------------------------------------- REAL(KIND=real_kind), DIMENSION(:), INTENT(IN) :: A REAL(KIND=real_kind), DIMENSION(:), INTENT(IN) :: B REAL(KIND=real_kind), DIMENSION(:), INTENT(IN), OPTIONAL :: WEIGHT LOGICAL(KIND=log_kind), DIMENSION(:), INTENT(IN), OPTIONAL :: MASK REAL(KIND=real_kind), INTENT(IN), OPTIONAL :: RELTOL, ABSTOL !--------------------------------------------------------------------------- ! local variables !--------------------------------------------------------------------------- CHARACTER(LEN=*), PARAMETER :: sub_name = 'equal_1D_ss' REAL(KIND=real_kind) :: reltol_actual, abstol_actual REAL(KIND=real_kind) :: diff, mag IF (SIZE(A) /= SIZE(B)) THEN equal_1D_ss = .FALSE. RETURN END IF IF (PRESENT(WEIGHT)) THEN IF (SIZE(A) /= SIZE(WEIGHT)) THEN CALL msg_write(sub_name, 'size mismatch between A & WEIGHT') END IF END IF IF (PRESENT(MASK)) THEN IF (SIZE(A) /= SIZE(MASK)) THEN CALL msg_write(sub_name, 'size mismatch between A & MASK') END IF END IF IF (PRESENT(RELTOL)) THEN reltol_actual = RELTOL ELSE reltol_actual = 1.0e-4_real_kind END IF IF (PRESENT(ABSTOL)) THEN abstol_actual = ABSTOL ELSE abstol_actual = 0.0_real_kind END IF equal_1D_ss = .FALSE. diff = rms(A - B, WEIGHT, MASK) IF (diff < abstol_actual) equal_1D_ss = .TRUE. mag = MAX(rms(A, WEIGHT, MASK), rms(B, WEIGHT, MASK)) IF (diff < mag * reltol_actual) equal_1D_ss = .TRUE. END FUNCTION equal_1D_ss !***************************************************************************** LOGICAL FUNCTION equal_1D_sd(A, B, WEIGHT, MASK, RELTOL, ABSTOL) !--------------------------------------------------------------------------- ! arguments !--------------------------------------------------------------------------- REAL(KIND=real_kind), DIMENSION(:), INTENT(IN) :: A REAL(KIND=dbl_kind), DIMENSION(:), INTENT(IN) :: B REAL(KIND=real_kind), DIMENSION(:), INTENT(IN), OPTIONAL :: WEIGHT LOGICAL(KIND=log_kind), DIMENSION(:), INTENT(IN), OPTIONAL :: MASK REAL(KIND=real_kind), INTENT(IN), OPTIONAL :: RELTOL, ABSTOL !--------------------------------------------------------------------------- ! local variables !--------------------------------------------------------------------------- CHARACTER(LEN=*), PARAMETER :: sub_name = 'equal_1D_sd' REAL(KIND=real_kind), DIMENSION(SIZE(B)) :: B_real IF (SIZE(A) /= SIZE(B)) THEN equal_1D_sd = .FALSE. RETURN END IF IF (PRESENT(WEIGHT)) THEN IF (SIZE(A) /= SIZE(WEIGHT)) THEN CALL msg_write(sub_name, 'size mismatch between A & WEIGHT') END IF END IF IF (PRESENT(MASK)) THEN IF (SIZE(A) /= SIZE(MASK)) THEN CALL msg_write(sub_name, 'size mismatch between A & MASK') END IF END IF B_real = REAL(B, real_kind) equal_1D_sd = equal_1D_ss(A, B_real, WEIGHT, MASK, RELTOL, ABSTOL) END FUNCTION equal_1D_sd !***************************************************************************** LOGICAL FUNCTION equal_1D_ds(A, B, WEIGHT, MASK, RELTOL, ABSTOL) !--------------------------------------------------------------------------- ! arguments !--------------------------------------------------------------------------- REAL(KIND=dbl_kind), DIMENSION(:), INTENT(IN) :: A REAL(KIND=real_kind), DIMENSION(:), INTENT(IN) :: B REAL(KIND=real_kind), DIMENSION(:), INTENT(IN), OPTIONAL :: WEIGHT LOGICAL(KIND=log_kind), DIMENSION(:), INTENT(IN), OPTIONAL :: MASK REAL(KIND=real_kind), INTENT(IN), OPTIONAL :: RELTOL, ABSTOL !--------------------------------------------------------------------------- ! local variables !--------------------------------------------------------------------------- CHARACTER(LEN=*), PARAMETER :: sub_name = 'equal_1D_ds' REAL(KIND=real_kind), DIMENSION(SIZE(A)) :: A_real IF (SIZE(A) /= SIZE(B)) THEN equal_1D_ds = .FALSE. RETURN END IF IF (PRESENT(WEIGHT)) THEN IF (SIZE(A) /= SIZE(WEIGHT)) THEN CALL msg_write(sub_name, 'size mismatch between A & WEIGHT') END IF END IF IF (PRESENT(MASK)) THEN IF (SIZE(A) /= SIZE(MASK)) THEN CALL msg_write(sub_name, 'size mismatch between A & MASK') END IF END IF A_real = REAL(A, real_kind) equal_1D_ds = equal_1D_ss(A_real, B, WEIGHT, MASK, RELTOL, ABSTOL) END FUNCTION equal_1D_ds !***************************************************************************** LOGICAL FUNCTION equal_1D_dd(A, B, WEIGHT, MASK, RELTOL, ABSTOL) !--------------------------------------------------------------------------- ! arguments !--------------------------------------------------------------------------- REAL(KIND=dbl_kind), DIMENSION(:), INTENT(IN) :: A REAL(KIND=dbl_kind), DIMENSION(:), INTENT(IN) :: B REAL(KIND=dbl_kind), DIMENSION(:), INTENT(IN), OPTIONAL :: WEIGHT LOGICAL(KIND=log_kind), DIMENSION(:), INTENT(IN), OPTIONAL :: MASK REAL(KIND=dbl_kind), INTENT(IN), OPTIONAL :: RELTOL, ABSTOL !--------------------------------------------------------------------------- ! local variables !--------------------------------------------------------------------------- CHARACTER(LEN=*), PARAMETER :: sub_name = 'equal_1D_dd' REAL(KIND=dbl_kind) :: reltol_actual, abstol_actual REAL(KIND=dbl_kind) :: diff, mag IF (SIZE(A) /= SIZE(B)) THEN equal_1D_dd = .FALSE. RETURN END IF IF (PRESENT(WEIGHT)) THEN IF (SIZE(A) /= SIZE(WEIGHT)) THEN CALL msg_write(sub_name, 'size mismatch between A & WEIGHT') END IF END IF IF (PRESENT(MASK)) THEN IF (SIZE(A) /= SIZE(MASK)) THEN CALL msg_write(sub_name, 'size mismatch between A & MASK') END IF END IF IF (PRESENT(RELTOL)) THEN reltol_actual = RELTOL ELSE reltol_actual = 1.0e-8_dbl_kind END IF IF (PRESENT(ABSTOL)) THEN abstol_actual = ABSTOL ELSE abstol_actual = 0.0_dbl_kind END IF equal_1D_dd = .FALSE. diff = rms(A - B, WEIGHT, MASK) IF (diff < abstol_actual) equal_1D_dd = .TRUE. mag = MAX(rms(A, WEIGHT, MASK), rms(B, WEIGHT, MASK)) IF (diff < mag * reltol_actual) equal_1D_dd = .TRUE. END FUNCTION equal_1D_dd !***************************************************************************** LOGICAL FUNCTION equal_2D_ss(A, B, WEIGHT, MASK, RELTOL, ABSTOL) !--------------------------------------------------------------------------- ! arguments !--------------------------------------------------------------------------- REAL(KIND=real_kind), DIMENSION(:,:), INTENT(IN) :: A REAL(KIND=real_kind), DIMENSION(:,:), INTENT(IN) :: B REAL(KIND=real_kind), DIMENSION(:,:), INTENT(IN), OPTIONAL :: WEIGHT LOGICAL(KIND=log_kind), DIMENSION(:,:), INTENT(IN), OPTIONAL :: MASK REAL(KIND=real_kind), INTENT(IN), OPTIONAL :: RELTOL, ABSTOL !--------------------------------------------------------------------------- ! local variables !--------------------------------------------------------------------------- CHARACTER(LEN=*), PARAMETER :: sub_name = 'equal_2D_ss' REAL(KIND=real_kind) :: reltol_actual, abstol_actual REAL(KIND=real_kind) :: diff, mag IF (SIZE(A,1) /= SIZE(B,1) .OR. SIZE(A,2) /= SIZE(B,2)) THEN equal_2D_ss = .FALSE. RETURN END IF IF (PRESENT(WEIGHT)) THEN IF (SIZE(A,1) /= SIZE(WEIGHT,1) .OR. SIZE(A,2) /= SIZE(WEIGHT,2)) THEN CALL msg_write(sub_name, 'size mismatch between A & WEIGHT') END IF END IF IF (PRESENT(MASK)) THEN IF (SIZE(A,1) /= SIZE(MASK,1) .OR. SIZE(A,2) /= SIZE(MASK,2)) THEN CALL msg_write(sub_name, 'size mismatch between A & MASK') END IF END IF IF (PRESENT(RELTOL)) THEN reltol_actual = RELTOL ELSE reltol_actual = 1.0e-4_real_kind END IF IF (PRESENT(ABSTOL)) THEN abstol_actual = ABSTOL ELSE abstol_actual = 0.0_real_kind END IF equal_2D_ss = .FALSE. diff = rms(A - B, WEIGHT, MASK) IF (diff < abstol_actual) equal_2D_ss = .TRUE. mag = MAX(rms(A, WEIGHT, MASK), rms(B, WEIGHT, MASK)) IF (diff < mag * reltol_actual) equal_2D_ss = .TRUE. END FUNCTION equal_2D_ss !***************************************************************************** LOGICAL FUNCTION equal_2D_sd(A, B, WEIGHT, MASK, RELTOL, ABSTOL) !--------------------------------------------------------------------------- ! arguments !--------------------------------------------------------------------------- REAL(KIND=real_kind), DIMENSION(:,:), INTENT(IN) :: A REAL(KIND=dbl_kind), DIMENSION(:,:), INTENT(IN) :: B REAL(KIND=real_kind), DIMENSION(:,:), INTENT(IN), OPTIONAL :: WEIGHT LOGICAL(KIND=log_kind), DIMENSION(:,:), INTENT(IN), OPTIONAL :: MASK REAL(KIND=real_kind), INTENT(IN), OPTIONAL :: RELTOL, ABSTOL !--------------------------------------------------------------------------- ! local variables !--------------------------------------------------------------------------- CHARACTER(LEN=*), PARAMETER :: sub_name = 'equal_2D_sd' REAL(KIND=real_kind), DIMENSION(SIZE(B,1), SIZE(B,2)) :: B_real IF (SIZE(A,1) /= SIZE(B,1) .OR. SIZE(A,2) /= SIZE(B,2)) THEN equal_2D_sd = .FALSE. RETURN END IF IF (PRESENT(WEIGHT)) THEN IF (SIZE(A,1) /= SIZE(WEIGHT,1) .OR. SIZE(A,2) /= SIZE(WEIGHT,2)) THEN CALL msg_write(sub_name, 'size mismatch between A & WEIGHT') END IF END IF IF (PRESENT(MASK)) THEN IF (SIZE(A,1) /= SIZE(MASK,1) .OR. SIZE(A,2) /= SIZE(MASK,2)) THEN CALL msg_write(sub_name, 'size mismatch between A & MASK') END IF END IF B_real = REAL(B, real_kind) equal_2D_sd = equal_2D_ss(A, B_real, WEIGHT, MASK, RELTOL, ABSTOL) END FUNCTION equal_2D_sd !***************************************************************************** LOGICAL FUNCTION equal_2D_ds(A, B, WEIGHT, MASK, RELTOL, ABSTOL) !--------------------------------------------------------------------------- ! arguments !--------------------------------------------------------------------------- REAL(KIND=dbl_kind), DIMENSION(:,:), INTENT(IN) :: A REAL(KIND=real_kind), DIMENSION(:,:), INTENT(IN) :: B REAL(KIND=real_kind), DIMENSION(:,:), INTENT(IN), OPTIONAL :: WEIGHT LOGICAL(KIND=log_kind), DIMENSION(:,:), INTENT(IN), OPTIONAL :: MASK REAL(KIND=real_kind), INTENT(IN), OPTIONAL :: RELTOL, ABSTOL !--------------------------------------------------------------------------- ! local variables !--------------------------------------------------------------------------- CHARACTER(LEN=*), PARAMETER :: sub_name = 'equal_2D_ds' REAL(KIND=real_kind), DIMENSION(SIZE(A,1), SIZE(A,2)) :: A_real IF (SIZE(A,1) /= SIZE(B,1) .OR. SIZE(A,2) /= SIZE(B,2)) THEN equal_2D_ds = .FALSE. RETURN END IF IF (PRESENT(WEIGHT)) THEN IF (SIZE(A,1) /= SIZE(WEIGHT,1) .OR. SIZE(A,2) /= SIZE(WEIGHT,2)) THEN CALL msg_write(sub_name, 'size mismatch between A & WEIGHT') END IF END IF IF (PRESENT(MASK)) THEN IF (SIZE(A,1) /= SIZE(MASK,1) .OR. SIZE(A,2) /= SIZE(MASK,2)) THEN CALL msg_write(sub_name, 'size mismatch between A & MASK') END IF END IF A_real = REAL(A, real_kind) equal_2D_ds = equal_2D_ss(A_real, B, WEIGHT, MASK, RELTOL, ABSTOL) END FUNCTION equal_2D_ds !***************************************************************************** LOGICAL FUNCTION equal_2D_dd(A, B, WEIGHT, MASK, RELTOL, ABSTOL) !--------------------------------------------------------------------------- ! arguments !--------------------------------------------------------------------------- REAL(KIND=dbl_kind), DIMENSION(:,:), INTENT(IN) :: A REAL(KIND=dbl_kind), DIMENSION(:,:), INTENT(IN) :: B REAL(KIND=dbl_kind), DIMENSION(:,:), INTENT(IN), OPTIONAL :: WEIGHT LOGICAL(KIND=log_kind), DIMENSION(:,:), INTENT(IN), OPTIONAL :: MASK REAL(KIND=dbl_kind), INTENT(IN), OPTIONAL :: RELTOL, ABSTOL !--------------------------------------------------------------------------- ! local variables !--------------------------------------------------------------------------- CHARACTER(LEN=*), PARAMETER :: sub_name = 'equal_2D_dd' REAL(KIND=dbl_kind) :: reltol_actual, abstol_actual REAL(KIND=dbl_kind) :: diff, mag IF (SIZE(A,1) /= SIZE(B,1) .OR. SIZE(A,2) /= SIZE(B,2)) THEN equal_2D_dd = .FALSE. RETURN END IF IF (PRESENT(WEIGHT)) THEN IF (SIZE(A,1) /= SIZE(WEIGHT,1) .OR. SIZE(A,2) /= SIZE(WEIGHT,2)) THEN CALL msg_write(sub_name, 'size mismatch between A & WEIGHT') END IF END IF IF (PRESENT(MASK)) THEN IF (SIZE(A,1) /= SIZE(MASK,1) .OR. SIZE(A,2) /= SIZE(MASK,2)) THEN CALL msg_write(sub_name, 'size mismatch between A & MASK') END IF END IF IF (PRESENT(RELTOL)) THEN reltol_actual = RELTOL ELSE reltol_actual = 1.0e-8_dbl_kind END IF IF (PRESENT(ABSTOL)) THEN abstol_actual = ABSTOL ELSE abstol_actual = 0.0_dbl_kind END IF equal_2D_dd = .FALSE. diff = rms(A - B, WEIGHT, MASK) IF (diff < abstol_actual) equal_2D_dd = .TRUE. mag = MAX(rms(A, WEIGHT, MASK), rms(B, WEIGHT, MASK)) IF (diff < mag * reltol_actual) equal_2D_dd = .TRUE. END FUNCTION equal_2D_dd !***************************************************************************** END MODULE array_tools