[524] | 1 | ! |
---|
[1403] | 2 | ! $Id: extrapol.f90 5246 2024-10-21 12:58:45Z aborella $ |
---|
[524] | 3 | ! |
---|
[5246] | 4 | ! |
---|
| 5 | ! |
---|
| 6 | SUBROUTINE extrapol (pfild, kxlon, kylat, pmask, & |
---|
| 7 | norsud, ldper, knbor, pwork) |
---|
| 8 | IMPLICIT none |
---|
| 9 | ! |
---|
| 10 | ! OASIS routine (Adaptation: Laurent Li, le 14 mars 1997) |
---|
| 11 | ! Fill up missed values by using the neighbor points |
---|
| 12 | ! |
---|
| 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 |
---|
| 20 | ! |
---|
| 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) |
---|
| 25 | ! |
---|
| 26 | ! We search over the eight closest neighbors |
---|
| 27 | ! |
---|
| 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 |
---|
| 32 | ! |
---|
| 33 | ! |
---|
| 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 |
---|
| 46 | ! |
---|
| 47 | incre = 0 |
---|
| 48 | ! |
---|
| 49 | DO j = 1, kylat |
---|
| 50 | DO i = 1, kxlon |
---|
| 51 | pwork(i,j) = pfild(i,j) |
---|
| 52 | ENDDO |
---|
| 53 | ENDDO |
---|
| 54 | ! |
---|
| 55 | !* To avoid problems in floating point tests |
---|
| 56 | zwmsk = pmask - 1.0 |
---|
| 57 | ! |
---|
[524] | 58 | 200 CONTINUE |
---|
[5246] | 59 | incre = incre + 1 |
---|
| 60 | DO j = 1, kylat |
---|
| 61 | DO i = 1, kxlon |
---|
| 62 | IF (pfild(i,j).GT. zwmsk) THEN |
---|
| 63 | pwork(i,j) = pfild(i,j) |
---|
| 64 | inbor = 0 |
---|
| 65 | ideb = 1 |
---|
| 66 | ifin = 9 |
---|
| 67 | ! |
---|
| 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) |
---|
| 78 | ! |
---|
| 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) |
---|
| 89 | ! |
---|
| 90 | !* Correct latitude bounds if southernmost or northernmost points |
---|
| 91 | IF (j .EQ. 1) ideb = 4 |
---|
| 92 | IF (j .EQ. kylat) ifin = 6 |
---|
| 93 | ! |
---|
| 94 | !* Account for periodicity in longitude |
---|
| 95 | ! |
---|
| 96 | IF (ldper) THEN |
---|
| 97 | IF (i .EQ. kxlon) THEN |
---|
| 98 | ix(3) = 1 |
---|
| 99 | ix(6) = 1 |
---|
| 100 | ix(9) = 1 |
---|
| 101 | ELSE IF (i .EQ. 1) THEN |
---|
| 102 | ix(1) = kxlon |
---|
| 103 | ix(4) = kxlon |
---|
| 104 | ix(7) = kxlon |
---|
| 105 | ENDIF |
---|
| 106 | ELSE |
---|
| 107 | IF (i .EQ. 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 .EQ. 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 |
---|
| 123 | ! |
---|
| 124 | IF (i .EQ. 1 .OR. i .EQ. 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) |
---|
| 131 | ! |
---|
| 132 | ideb = 1 |
---|
| 133 | ifin = 6 |
---|
| 134 | IF (j .EQ. 1) ideb = 3 |
---|
| 135 | IF (j .EQ. kylat) ifin = 4 |
---|
| 136 | ENDIF |
---|
| 137 | ENDIF ! end for ldper test |
---|
| 138 | ! |
---|
| 139 | !* Find unmasked neighbors |
---|
| 140 | ! |
---|
| 141 | DO k = ideb, ifin |
---|
| 142 | zmask(k) = 0. |
---|
| 143 | ilon = ix(k) |
---|
| 144 | jlat = jy(k) |
---|
| 145 | IF (pfild(ilon,jlat) .LT. zwmsk) THEN |
---|
| 146 | zmask(k) = 1. |
---|
| 147 | inbor = inbor + 1 |
---|
| 148 | ENDIF |
---|
| 149 | END DO |
---|
| 150 | ! |
---|
| 151 | !* Not enough points around point P are unmasked; interpolation on P |
---|
| 152 | ! will be done in a future call to extrap. |
---|
| 153 | ! |
---|
| 154 | IF (inbor .GE. 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 |
---|
| 163 | ! |
---|
| 164 | ENDIF |
---|
| 165 | END DO |
---|
| 166 | END DO |
---|
| 167 | ! |
---|
| 168 | !* 3. Writing back unmasked field in pfild |
---|
| 169 | ! ------------------------------------ |
---|
| 170 | ! |
---|
| 171 | !* pfild then contains: |
---|
| 172 | ! - Values which were not masked |
---|
| 173 | ! - Interpolated values from the inbor neighbors |
---|
| 174 | ! - Values which are not yet interpolated |
---|
| 175 | ! |
---|
| 176 | idoit = 0 |
---|
| 177 | DO j = 1, kylat |
---|
| 178 | DO i = 1, kxlon |
---|
| 179 | IF (pwork(i,j) .GT. zwmsk) idoit = idoit + 1 |
---|
| 180 | pfild(i,j) = pwork(i,j) |
---|
| 181 | ENDDO |
---|
| 182 | ENDDO |
---|
| 183 | ! |
---|
| 184 | IF (idoit .ne. 0) GOTO 200 |
---|
| 185 | !cc PRINT*, "Number of extrapolation steps incre =", incre |
---|
| 186 | ! |
---|
| 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 |
---|
| 199 | ! |
---|
| 200 | RETURN |
---|
| 201 | END SUBROUTINE extrapol |
---|