[2759] | 1 | MODULE module_positive_definite |
---|
| 2 | |
---|
| 3 | USE module_wrf_error ! frame |
---|
| 4 | |
---|
| 5 | CONTAINS |
---|
| 6 | |
---|
| 7 | SUBROUTINE positive_definite_slab( f, & |
---|
| 8 | ids, ide, jds, jde, kds, kde, & |
---|
| 9 | ims, ime, jms, jme, kms, kme, & |
---|
| 10 | its, ite, jts, jte, kts, kte) |
---|
| 11 | |
---|
| 12 | IMPLICIT NONE |
---|
| 13 | |
---|
| 14 | ! Arguments |
---|
| 15 | INTEGER, INTENT(IN ) :: ids, ide, jds, jde, kds, kde, & |
---|
| 16 | ims, ime, jms, jme, kms, kme, & |
---|
| 17 | its, ite, jts, jte, kts, kte |
---|
| 18 | REAL, DIMENSION( ims:ime, kms:kme, jms:jme ), INTENT(INOUT) :: f |
---|
| 19 | |
---|
| 20 | ! Local variables |
---|
| 21 | REAL, DIMENSION(:), ALLOCATABLE :: line |
---|
| 22 | INTEGER :: j, k, i_end, j_end, k_end |
---|
| 23 | REAL :: fmin, ftotal_pre, rftotal_post |
---|
| 24 | |
---|
| 25 | ! Initialize variables |
---|
| 26 | i_end = ide-1 |
---|
| 27 | j_end = MIN(jte, jde-1) |
---|
| 28 | k_end = kte-1 |
---|
| 29 | ! Only do anything if we have to... |
---|
| 30 | IF (ANY(f(ids:i_end,kts:k_end,jts:j_end) < 0.)) THEN |
---|
| 31 | ! number of points in the X direction, not including U-stagger |
---|
| 32 | ALLOCATE(line(ide-ids)) |
---|
| 33 | DO j = jts, j_end |
---|
| 34 | DO k = kts, kte-1 |
---|
| 35 | !while_lt_0_loop: DO WHILE (ANY(f(ids:i_end,k,j) < 0.)) |
---|
| 36 | f_lt_0: IF (ANY(f(ids:i_end,k,j) < 0.)) THEN |
---|
| 37 | line(:) = f(ids:i_end,k,j) |
---|
| 38 | ! This is actually an integration over x assuming dx is constant |
---|
| 39 | ftotal_pre = SUM(line) |
---|
| 40 | ! If the total is negative, set everything to 0. and exit |
---|
| 41 | IF (ftotal_pre < 0.) THEN |
---|
| 42 | line(:) = 0. |
---|
| 43 | ELSE |
---|
| 44 | ! Value to add to array to make sure every element is > 0. |
---|
| 45 | fmin = MINVAL(line) |
---|
| 46 | line(:) = line(:) - fmin ! fmin is negative... |
---|
| 47 | rftotal_post = 1./SUM(line) |
---|
| 48 | line = line*ftotal_pre*rftotal_post |
---|
| 49 | ! The following error can naturally occur on 32-bit machines: |
---|
| 50 | !IF (SUM(line) /= ftotal_pre) THEN |
---|
| 51 | ! write(wrf_err_message,*) 'ERROR: module_positive_definite, ',& |
---|
| 52 | ! 'mismatching sums ',j,k,ftotal_pre,& |
---|
| 53 | ! SUM(line),fmin,1./rftotal_post |
---|
| 54 | ! write(*,*) line |
---|
| 55 | ! CALL wrf_error_fatal( wrf_err_message ) |
---|
| 56 | !END IF |
---|
| 57 | END IF |
---|
| 58 | f(ids:i_end,k,j) = line(:) |
---|
| 59 | END IF f_lt_0 |
---|
| 60 | !END DO while_lt_0_loop |
---|
| 61 | END DO |
---|
| 62 | END DO |
---|
| 63 | DEALLOCATE(line) |
---|
| 64 | END IF |
---|
| 65 | |
---|
| 66 | END SUBROUTINE positive_definite_slab |
---|
| 67 | |
---|
| 68 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
---|
| 69 | |
---|
| 70 | SUBROUTINE positive_definite_sheet( f, f_total, nx, ny ) |
---|
| 71 | |
---|
| 72 | IMPLICIT NONE |
---|
| 73 | |
---|
| 74 | ! Arguments |
---|
| 75 | INTEGER, INTENT(IN ) :: nx, ny |
---|
| 76 | REAL, DIMENSION( nx, ny ), INTENT(INOUT) :: f |
---|
| 77 | REAL, DIMENSION( ny ), INTENT(IN) :: f_total |
---|
| 78 | |
---|
| 79 | ! Local variables |
---|
| 80 | REAL, DIMENSION(:), ALLOCATABLE :: line |
---|
| 81 | INTEGER :: iy |
---|
| 82 | REAL :: fmin, rftotal_post, sum_line |
---|
| 83 | REAL, PARAMETER :: eps = 1.0e-15 |
---|
| 84 | |
---|
| 85 | ! Only do anything if we have to... |
---|
| 86 | IF (ANY(f < 0.)) THEN |
---|
| 87 | ALLOCATE(line(nx)) |
---|
| 88 | DO iy = 1, ny |
---|
| 89 | !while_lt_0_loop: DO WHILE (ANY(f(:,iy) < 0.)) |
---|
| 90 | f_lt_0: IF (ANY(f(:,iy) < 0.)) THEN |
---|
| 91 | line(:) = f(:,iy) |
---|
| 92 | ! If the total is negative, set everything to 0. and exit |
---|
| 93 | IF (f_total(iy) < 0.) THEN |
---|
| 94 | line(:) = 0. |
---|
| 95 | ELSE |
---|
| 96 | ! Value to add to array to make sure every element is > 0. |
---|
| 97 | fmin = MINVAL(line) |
---|
| 98 | line(:) = line(:) - fmin ! fmin is negative... |
---|
| 99 | sum_line = SUM(line) |
---|
| 100 | IF(sum_line > eps) THEN |
---|
| 101 | rftotal_post = 1./sum_line |
---|
| 102 | line = line*f_total(iy)*rftotal_post |
---|
| 103 | ELSE |
---|
| 104 | line(:) = 0. |
---|
| 105 | END IF |
---|
| 106 | ! The following error can naturally occur on 32-bit machines: |
---|
| 107 | !IF (SUM(line) /= f_total(iy)) THEN |
---|
| 108 | ! write(wrf_err_message,*) 'ERROR: module_positive_definite, ',& |
---|
| 109 | ! 'mismatching sums ',iy,f_total(iy), & |
---|
| 110 | ! SUM(line),fmin,1./rftotal_post |
---|
| 111 | ! write(*,*) line |
---|
| 112 | ! CALL wrf_error_fatal( wrf_err_message ) |
---|
| 113 | !END IF |
---|
| 114 | END IF |
---|
| 115 | f(:,iy) = line(:) |
---|
| 116 | END IF f_lt_0 |
---|
| 117 | !END DO while_lt_0_loop |
---|
| 118 | END DO |
---|
| 119 | DEALLOCATE(line) |
---|
| 120 | END IF |
---|
| 121 | |
---|
| 122 | END SUBROUTINE positive_definite_sheet |
---|
| 123 | |
---|
| 124 | END MODULE module_positive_definite |
---|