Ignore:
Timestamp:
Oct 21, 2024, 2:58:45 PM (23 hours ago)
Author:
abarral
Message:

Convert fixed-form to free-form sources .F -> .{f,F}90
(WIP: some .F remain, will be handled in subsequent commits)

File:
1 moved

Legend:

Unmodified
Added
Removed
  • LMDZ6/trunk/libf/dyn3d_common/extrapol.f90

    r5245 r5246  
    22! $Id$
    33!
    4 C
    5 C
    6       SUBROUTINE extrapol (pfild, kxlon, kylat, pmask,
    7      .                   norsud, ldper, knbor, pwork)
    8       IMPLICIT none
    9 c
    10 c OASIS routine (Adaptation: Laurent Li, le 14 mars 1997)
    11 c Fill up missed values by using the neighbor points
    12 c
    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 c
    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 C
    26 C  We search over the eight closest neighbors
    27 C
    28 C            j+1  7  8  9
    29 C              j  4  5  6    Current point 5 --> (i,j)
    30 C            j-1  1  2  3
    31 C                i-1 i i+1
    32 c
    33 c
    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 c
    47       incre = 0
    48 c
    49       DO j = 1, kylat
    50       DO i = 1, kxlon
    51          pwork(i,j) = pfild(i,j)
    52       ENDDO
    53       ENDDO
    54 c
    55 C* To avoid problems in floating point tests
    56       zwmsk = pmask - 1.0
    57 c
     4!
     5!
     6SUBROUTINE 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  !
    5858200   CONTINUE
    59       incre = incre + 1
    60       DO 99999 j = 1, kylat
    61       DO 99999 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 C
    68 C* 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 C
    79 C* 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 C
    90 C* Correct latitude bounds if southernmost or northernmost points
    91          IF (j .EQ. 1) ideb = 4
    92          IF (j .EQ. kylat) ifin = 6
    93 C
    94 C* Account for periodicity in longitude
    95 C
    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 C
    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 C
    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 C
    139 C* Find unmasked neighbors
    140 C
    141          DO 230 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  230     CONTINUE
    150 C
    151 C* Not enough points around point P are unmasked; interpolation on P
    152 C  will be done in a future call to extrap.
    153 C
    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 C
    164       ENDIF
    165 99999 CONTINUE
    166 C
    167 C*    3. Writing back unmasked field in pfild
    168 C        ------------------------------------
    169 C
    170 C* pfild then contains:
    171 C     - Values which were not masked
    172 C     - Interpolated values from the inbor neighbors
    173 C     - Values which are not yet interpolated
    174 C
    175       idoit = 0
    176       DO j = 1, kylat
    177       DO i = 1, kxlon
    178          IF (pwork(i,j) .GT. zwmsk) idoit = idoit + 1
    179          pfild(i,j) = pwork(i,j)
    180       ENDDO
    181       ENDDO
    182 c
    183       IF (idoit .ne. 0) GOTO 200
    184 ccc      PRINT*, "Number of extrapolation steps incre =", incre
    185 c
    186       IF (norsud) THEN
    187          DO j = 1, kylat
    188          DO i = 1, kxlon
    189             pwork(i,j) = pfild(i,kylat-j+1)
    190          ENDDO
    191          ENDDO
    192          DO j = 1, kylat
    193          DO i = 1, kxlon
    194             pfild(i,j) = pwork(i,j)
    195          ENDDO
    196          ENDDO
    197       ENDIF
    198 c
    199       RETURN
    200       END
     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
     201END SUBROUTINE extrapol
Note: See TracChangeset for help on using the changeset viewer.