MODULE module_positive_definite
USE module_wrf_error
! frame
CONTAINS
SUBROUTINE positive_definite_slab( f, &,1
ids, ide, jds, jde, kds, kde, &
ims, ime, jms, jme, kms, kme, &
its, ite, jts, jte, kts, kte)
IMPLICIT NONE
! Arguments
INTEGER, INTENT(IN ) :: ids, ide, jds, jde, kds, kde, &
ims, ime, jms, jme, kms, kme, &
its, ite, jts, jte, kts, kte
REAL, DIMENSION( ims:ime, kms:kme, jms:jme ), INTENT(INOUT) :: f
! Local variables
REAL, DIMENSION(:), ALLOCATABLE :: line
INTEGER :: j, k, i_end, j_end, k_end
REAL :: fmin, ftotal_pre, rftotal_post
! Initialize variables
i_end = ide-1
j_end = MIN(jte, jde-1)
k_end = kte-1
! Only do anything if we have to...
IF (ANY(f(ids:i_end,kts:k_end,jts:j_end) < 0.)) THEN
! number of points in the X direction, not including U-stagger
ALLOCATE(line(ide-ids))
DO j = jts, j_end
DO k = kts, kte-1
!while_lt_0_loop: DO WHILE (ANY(f(ids:i_end,k,j) < 0.))
f_lt_0: IF (ANY(f(ids:i_end,k,j) < 0.)) THEN
line(:) = f
(ids:i_end,k,j)
! This is actually an integration over x assuming dx is constant
ftotal_pre = SUM(line)
! If the total is negative, set everything to 0. and exit
IF (ftotal_pre < 0.) THEN
line(:) = 0.
ELSE
! Value to add to array to make sure every element is > 0.
fmin = MINVAL(line)
line(:) = line(:) - fmin ! fmin is negative...
rftotal_post = 1./SUM(line)
line = line*ftotal_pre*rftotal_post
! The following error can naturally occur on 32-bit machines:
!IF (SUM(line) /= ftotal_pre) THEN
! write(wrf_err_message,*) 'ERROR: module_positive_definite, ',&
! 'mismatching sums ',j,k,ftotal_pre,&
! SUM(line),fmin,1./rftotal_post
! write(*,*) line
! CALL wrf_error_fatal( wrf_err_message )
!END IF
END IF
f(ids:i_end,k,j) = line(:)
END IF f_lt_0
!END DO while_lt_0_loop
END DO
END DO
DEALLOCATE(line)
END IF
END SUBROUTINE positive_definite_slab
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
SUBROUTINE positive_definite_sheet( f, f_total, nx, ny ),1
IMPLICIT NONE
! Arguments
INTEGER, INTENT(IN ) :: nx, ny
REAL, DIMENSION( nx, ny ), INTENT(INOUT) :: f
REAL, DIMENSION( ny ), INTENT(IN) :: f_total
! Local variables
REAL, DIMENSION(:), ALLOCATABLE :: line
INTEGER :: iy
REAL :: fmin, rftotal_post, sum_line
REAL, PARAMETER :: eps = 1.0e-15
! Only do anything if we have to...
IF (ANY(f < 0.)) THEN
ALLOCATE(line(nx))
DO iy = 1, ny
!while_lt_0_loop: DO WHILE (ANY(f(:,iy) < 0.))
f_lt_0: IF (ANY(f(:,iy) < 0.)) THEN
line(:) = f
(:,iy)
! If the total is negative, set everything to 0. and exit
IF (f_total(iy) < 0.) THEN
line(:) = 0.
ELSE
! Value to add to array to make sure every element is > 0.
fmin = MINVAL(line)
line(:) = line(:) - fmin ! fmin is negative...
sum_line = SUM(line)
IF(sum_line > eps) THEN
rftotal_post = 1./sum_line
line = line*f_total(iy)*rftotal_post
ELSE
line(:) = 0.
END IF
! The following error can naturally occur on 32-bit machines:
!IF (SUM(line) /= f_total(iy)) THEN
! write(wrf_err_message,*) 'ERROR: module_positive_definite, ',&
! 'mismatching sums ',iy,f_total(iy), &
! SUM(line),fmin,1./rftotal_post
! write(*,*) line
! CALL wrf_error_fatal( wrf_err_message )
!END IF
END IF
f(:,iy) = line(:)
END IF f_lt_0
!END DO while_lt_0_loop
END DO
DEALLOCATE(line)
END IF
END SUBROUTINE positive_definite_sheet
END MODULE module_positive_definite