[5099] | 1 | |
---|
[1403] | 2 | ! $Id: extrapol.f90 5159 2024-08-02 19:58:25Z dcugnet $ |
---|
[5099] | 3 | |
---|
[5159] | 4 | |
---|
| 5 | |
---|
[5106] | 6 | SUBROUTINE extrapol(pfild, kxlon, kylat, pmask, & |
---|
[5105] | 7 | norsud, ldper, knbor, pwork) |
---|
[5134] | 8 | IMPLICIT NONE |
---|
[5159] | 9 | |
---|
[5105] | 10 | ! OASIS routine (Adaptation: Laurent Li, le 14 mars 1997) |
---|
| 11 | ! Fill up missed values by using the neighbor points |
---|
[5159] | 12 | |
---|
[5105] | 13 | INTEGER :: kxlon, kylat ! longitude and latitude dimensions (Input) |
---|
| 14 | INTEGER :: knbor ! minimum neighbor number (Input) |
---|
| 15 | LOGICAL :: norsud ! True if field is from North to South (Input) |
---|
| 16 | LOGICAL :: ldper ! True if take into account the periodicity (Input) |
---|
| 17 | REAL :: pmask ! mask value (Input) |
---|
| 18 | REAL :: pfild(kxlon,kylat) ! field to be extrapolated (Input/Output) |
---|
| 19 | REAL :: pwork(kxlon,kylat) ! working space |
---|
[5159] | 20 | |
---|
[5105] | 21 | REAL :: zwmsk |
---|
| 22 | INTEGER :: incre, idoit, i, j, k, inbor, ideb, ifin, ilon, jlat |
---|
| 23 | INTEGER :: ix(9), jy(9) ! index arrays for the neighbors coordinates |
---|
| 24 | REAL :: zmask(9) |
---|
[5159] | 25 | |
---|
[5105] | 26 | ! We search over the eight closest neighbors |
---|
[5159] | 27 | |
---|
[5105] | 28 | ! j+1 7 8 9 |
---|
| 29 | ! j 4 5 6 Current point 5 --> (i,j) |
---|
| 30 | ! j-1 1 2 3 |
---|
| 31 | ! i-1 i i+1 |
---|
[5159] | 32 | |
---|
| 33 | |
---|
[5105] | 34 | IF (norsud) THEN |
---|
| 35 | DO j = 1, kylat |
---|
| 36 | DO i = 1, kxlon |
---|
| 37 | pwork(i,j) = pfild(i,kylat-j+1) |
---|
| 38 | ENDDO |
---|
| 39 | ENDDO |
---|
| 40 | DO j = 1, kylat |
---|
| 41 | DO i = 1, kxlon |
---|
| 42 | pfild(i,j) = pwork(i,j) |
---|
| 43 | ENDDO |
---|
| 44 | ENDDO |
---|
| 45 | ENDIF |
---|
[5159] | 46 | |
---|
[5105] | 47 | incre = 0 |
---|
[5159] | 48 | |
---|
[5105] | 49 | DO j = 1, kylat |
---|
| 50 | DO i = 1, kxlon |
---|
| 51 | pwork(i,j) = pfild(i,j) |
---|
| 52 | ENDDO |
---|
| 53 | ENDDO |
---|
[5159] | 54 | |
---|
[5105] | 55 | !* To avoid problems in floating point tests |
---|
| 56 | zwmsk = pmask - 1.0 |
---|
[5159] | 57 | |
---|
[524] | 58 | 200 CONTINUE |
---|
[5105] | 59 | incre = incre + 1 |
---|
| 60 | DO j = 1, kylat |
---|
| 61 | DO i = 1, kxlon |
---|
| 62 | IF (pfild(i,j)> zwmsk) THEN |
---|
| 63 | pwork(i,j) = pfild(i,j) |
---|
| 64 | inbor = 0 |
---|
| 65 | ideb = 1 |
---|
| 66 | ifin = 9 |
---|
[5159] | 67 | |
---|
[5105] | 68 | !* Fill up ix array |
---|
| 69 | ix(1) = MAX (1,i-1) |
---|
| 70 | ix(2) = i |
---|
| 71 | ix(3) = MIN (kxlon,i+1) |
---|
| 72 | ix(4) = MAX (1,i-1) |
---|
| 73 | ix(5) = i |
---|
| 74 | ix(6) = MIN (kxlon,i+1) |
---|
| 75 | ix(7) = MAX (1,i-1) |
---|
| 76 | ix(8) = i |
---|
| 77 | ix(9) = MIN (kxlon,i+1) |
---|
[5159] | 78 | |
---|
[5105] | 79 | !* Fill up iy array |
---|
| 80 | jy(1) = MAX (1,j-1) |
---|
| 81 | jy(2) = MAX (1,j-1) |
---|
| 82 | jy(3) = MAX (1,j-1) |
---|
| 83 | jy(4) = j |
---|
| 84 | jy(5) = j |
---|
| 85 | jy(6) = j |
---|
| 86 | jy(7) = MIN (kylat,j+1) |
---|
| 87 | jy(8) = MIN (kylat,j+1) |
---|
| 88 | jy(9) = MIN (kylat,j+1) |
---|
[5159] | 89 | |
---|
[5105] | 90 | !* Correct latitude bounds if southernmost or northernmost points |
---|
| 91 | IF (j == 1) ideb = 4 |
---|
| 92 | IF (j == kylat) ifin = 6 |
---|
[5159] | 93 | |
---|
[5105] | 94 | !* Account for periodicity in longitude |
---|
[5159] | 95 | |
---|
[5105] | 96 | IF (ldper) THEN |
---|
| 97 | IF (i == kxlon) THEN |
---|
| 98 | ix(3) = 1 |
---|
| 99 | ix(6) = 1 |
---|
| 100 | ix(9) = 1 |
---|
| 101 | ELSE IF (i == 1) THEN |
---|
| 102 | ix(1) = kxlon |
---|
| 103 | ix(4) = kxlon |
---|
| 104 | ix(7) = kxlon |
---|
| 105 | ENDIF |
---|
| 106 | ELSE |
---|
| 107 | IF (i == 1) THEN |
---|
| 108 | ix(1) = i |
---|
| 109 | ix(2) = i + 1 |
---|
| 110 | ix(3) = i |
---|
| 111 | ix(4) = i + 1 |
---|
| 112 | ix(5) = i |
---|
| 113 | ix(6) = i + 1 |
---|
| 114 | ENDIF |
---|
| 115 | IF (i == kxlon) THEN |
---|
| 116 | ix(1) = i -1 |
---|
| 117 | ix(2) = i |
---|
| 118 | ix(3) = i - 1 |
---|
| 119 | ix(4) = i |
---|
| 120 | ix(5) = i - 1 |
---|
| 121 | ix(6) = i |
---|
| 122 | ENDIF |
---|
[5159] | 123 | |
---|
[5105] | 124 | IF (i == 1 .OR. i == kxlon) THEN |
---|
| 125 | jy(1) = MAX (1,j-1) |
---|
| 126 | jy(2) = MAX (1,j-1) |
---|
| 127 | jy(3) = j |
---|
| 128 | jy(4) = j |
---|
| 129 | jy(5) = MIN (kylat,j+1) |
---|
| 130 | jy(6) = MIN (kylat,j+1) |
---|
[5159] | 131 | |
---|
[5105] | 132 | ideb = 1 |
---|
| 133 | ifin = 6 |
---|
| 134 | IF (j == 1) ideb = 3 |
---|
| 135 | IF (j == kylat) ifin = 4 |
---|
| 136 | ENDIF |
---|
| 137 | ENDIF ! end for ldper test |
---|
[5159] | 138 | |
---|
[5105] | 139 | !* Find unmasked neighbors |
---|
[5159] | 140 | |
---|
[5105] | 141 | DO k = ideb, ifin |
---|
| 142 | zmask(k) = 0. |
---|
| 143 | ilon = ix(k) |
---|
| 144 | jlat = jy(k) |
---|
| 145 | IF (pfild(ilon,jlat) < zwmsk) THEN |
---|
| 146 | zmask(k) = 1. |
---|
| 147 | inbor = inbor + 1 |
---|
| 148 | ENDIF |
---|
| 149 | END DO |
---|
[5159] | 150 | |
---|
[5105] | 151 | !* Not enough points around point P are unmasked; interpolation on P |
---|
| 152 | ! will be done in a future CALL to extrap. |
---|
[5159] | 153 | |
---|
[5105] | 154 | IF (inbor >= knbor) THEN |
---|
| 155 | pwork(i,j) = 0. |
---|
| 156 | DO k = ideb, ifin |
---|
| 157 | ilon = ix(k) |
---|
| 158 | jlat = jy(k) |
---|
| 159 | pwork(i,j) = pwork(i,j) & |
---|
| 160 | + pfild(ilon,jlat) * zmask(k)/ REAL(inbor) |
---|
| 161 | ENDDO |
---|
| 162 | ENDIF |
---|
[5159] | 163 | |
---|
[5105] | 164 | ENDIF |
---|
| 165 | END DO |
---|
| 166 | END DO |
---|
[5159] | 167 | |
---|
[5105] | 168 | !* 3. Writing back unmasked field in pfild |
---|
| 169 | ! ------------------------------------ |
---|
[5159] | 170 | |
---|
[5105] | 171 | !* pfild then contains: |
---|
| 172 | ! - Values which were not masked |
---|
| 173 | ! - Interpolated values from the inbor neighbors |
---|
| 174 | ! - Values which are not yet interpolated |
---|
[5159] | 175 | |
---|
[5105] | 176 | idoit = 0 |
---|
| 177 | DO j = 1, kylat |
---|
| 178 | DO i = 1, kxlon |
---|
| 179 | IF (pwork(i,j) > zwmsk) idoit = idoit + 1 |
---|
| 180 | pfild(i,j) = pwork(i,j) |
---|
| 181 | ENDDO |
---|
| 182 | ENDDO |
---|
[5159] | 183 | |
---|
[5105] | 184 | IF (idoit /= 0) GOTO 200 |
---|
| 185 | !cc PRINT*, "Number of extrapolation steps incre =", incre |
---|
[5159] | 186 | |
---|
[5105] | 187 | IF (norsud) THEN |
---|
| 188 | DO j = 1, kylat |
---|
| 189 | DO i = 1, kxlon |
---|
| 190 | pwork(i,j) = pfild(i,kylat-j+1) |
---|
| 191 | ENDDO |
---|
| 192 | ENDDO |
---|
| 193 | DO j = 1, kylat |
---|
| 194 | DO i = 1, kxlon |
---|
| 195 | pfild(i,j) = pwork(i,j) |
---|
| 196 | ENDDO |
---|
| 197 | ENDDO |
---|
| 198 | ENDIF |
---|
[5159] | 199 | |
---|
[5105] | 200 | RETURN |
---|
| 201 | END SUBROUTINE extrapol |
---|